locked
can i add a listview in a WinJS.Binding.Template,and how to binding the itemDataSource of the inner listview

    Question

  • there is my HTML like this:

    <body>
         <div id="SubItemTemplate" data-win-control="WinJS.Binding.Template">
            <p data-win-bind="textContent: title"></p>
            <p data-win-bind="textContent: data"></p>
        </div>
    
        <div id="ItemTemplate" data-win-control="WinJS.Binding.Template">
            <div style="width: 300px">
                <p data-win-bind="textContent: title"></p>
                <p data-win-bind="textContent: data"></p>
                <div data-win-control="WinJS.UI.ListView"
                    data-win-options="{itemDataSource: data, itemTemplate: select('#SubItemTemplate'), layout: {type: WinJS.UI.GridLayout}}">
                </div>
            </div>
        </div>
    
        <div id="List" data-win-control="WinJS.UI.ListView" style="height: 100%;"
            data-win-options="{itemDataSource : Data.DataItem.dataSource, itemTemplate: select('#ItemTemplate'), layout: {type: WinJS.UI.GridLayout}}">
        </div>
    </body>

    and my js like this:

    var SubDataArray = [
            { title: "subtitle1", data: "data1" },
            { title: "subtitle2", data: "data2" },
            { title: "subtitle3", data: "data3" },
            { title: "subtitle4", data: "data4" },
            { title: "subtitle5", data: "data5" }
        ];
    
        var SubDataList = new WinJS.Binding.List(SubDataArray);
    
        var DataArray = [
            { title: "title1", data: SubDataList },
            { title: "title2", data: SubDataList },
            { title: "title3", data: SubDataList },
            { title: "title4", data: SubDataList },
            { title: "title5", data: SubDataList }
        ];
    
        var DataList = new WinJS.Binding.List(DataArray);
    
        var Members =
            {
                DataItem: DataList
            }
        WinJS.Namespace.define("Data", Members);

    how to binding the itemDataSource of the inner listview

    i know i can not write code like this"data-win-options="{itemDataSource: data", but who can tell me how to code?

    thanks.

    Friday, April 13, 2012 7:38 AM

Answers

  • Hi,

    You can use a function to return the template so that you can bind in JavaScript. A sample (style not added please do it yourself)

    function MainItemTemplate(itemPromise) {
        return itemPromise.then(function (currentItem) {
        
    
            var result = document.createElement("div");
    
            var body = document.createElement("div");
          
    
            // Display title
            var title = document.createElement("div");
            title.innerText = currentItem.data.title;
            body.appendChild(title);
    
         
            // Display nested ListView
            var nestedListView = document.createElement("div");
            var listView = new WinJS.UI.ListView(nestedListView);
            listView.itemDataSource = currentItem.data.data.dataSource;
            listView.itemTemplate = document.getElementById("SubItemTemplate");
            body.appendChild(nestedListView);
    
            result.appendChild(body);
            return result;
        
        });
    }
     <div id="SubItemTemplate" data-win-control="WinJS.Binding.Template">
            <p data-win-bind="textContent: title"></p>
            <p data-win-bind="textContent: data"></p>
        </div>
    
     
           
             <div id="listView3" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: Data.DataItem.dataSource, itemTemplate: MainItemTemplate, layout: { type: WinJS.UI.GridLayout } }">
        </div>



    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, April 17, 2012 2:53 AM
  • MainItemTemplate is defined inside an anonymous function so not visible to the HTML declarative processing.

    In your js code use WinJS.namespace.define() to expose the function to the HTML.

    WinJS.Namespace.define('myPage', {

            MainItemTemplate: MainItemTemplate
        });

    Then reference it in your control:

    itemTemplate:myPage.MainItemTemplate



    Jeff Sanders (MSFT)

    Thursday, August 16, 2012 6:53 PM
    Moderator
  • Thanks for the help.

    I also needed register the function using.

    WinJS.Utilities.markSupportedForProcessing(MainItemTemplate);

    Friday, August 17, 2012 9:20 AM

All replies

  • I found a listview sample:

    <div data-win-control="WinJS.UI.ListView"
                    data-win-bind:"winControl.itemDataSource: data.dataSource"
                    data-win-options="{itemTemplate: select('#SubItemTemplate'), selectionMode: 'none', layout: {type: WinJS.UI.GridLayout}}">
    </div>

    but the inner listview always can not show on screen.

    who can tell me why?

    Monday, April 16, 2012 2:25 AM
  • 各位大神没人知道么...急得我都用中文了

    Monday, April 16, 2012 5:55 AM
  • Hi,

    You can use a function to return the template so that you can bind in JavaScript. A sample (style not added please do it yourself)

    function MainItemTemplate(itemPromise) {
        return itemPromise.then(function (currentItem) {
        
    
            var result = document.createElement("div");
    
            var body = document.createElement("div");
          
    
            // Display title
            var title = document.createElement("div");
            title.innerText = currentItem.data.title;
            body.appendChild(title);
    
         
            // Display nested ListView
            var nestedListView = document.createElement("div");
            var listView = new WinJS.UI.ListView(nestedListView);
            listView.itemDataSource = currentItem.data.data.dataSource;
            listView.itemTemplate = document.getElementById("SubItemTemplate");
            body.appendChild(nestedListView);
    
            result.appendChild(body);
            return result;
        
        });
    }
     <div id="SubItemTemplate" data-win-control="WinJS.Binding.Template">
            <p data-win-bind="textContent: title"></p>
            <p data-win-bind="textContent: data"></p>
        </div>
    
     
           
             <div id="listView3" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: Data.DataItem.dataSource, itemTemplate: MainItemTemplate, layout: { type: WinJS.UI.GridLayout } }">
        </div>



    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, April 17, 2012 2:53 AM
  • Thanks for your help,it is very useful for me.

    and more question ,  is there any way to bind the data in HTML instead of in JS?

    Tuesday, April 17, 2012 3:52 AM
  • I have the same question about this, is there any way to bind the nested array to the list view or how to bind data to the nested list view via HTML?
    Friday, April 20, 2012 2:40 AM
  • I have the same question about this, is there any way to bind the nested array to the list view or how to bind data to the nested list view via HTML?

    I have this question as well.

    Saturday, May 05, 2012 12:48 AM
  • I have the same question
    Thursday, June 21, 2012 12:59 PM
  • I have the same question about this, is there any way to bind the nested array to the list view or how to bind data to the nested list view via HTML?

    Nice question, i also wants to know that.

    Thursday, June 21, 2012 1:12 PM
  • I have the same question re: binding a sub-listview in the HTML markup, as well.

    It seems that there should be a way to change the binding context of the itemDataSource of the sub-listview, since all of the other bindings in the template are in the context of the object bound to the `currentItem` of the top listview.

    Thursday, August 09, 2012 11:45 AM
  • I can't get this example to work properly. Also I'm working with a very complex HTML template using a complex grid layout so ideally I would like to be able to make a nested list using HTML. This has to be one of the most common tasks out there and this article seems to be the only one talking about it.

    Here is the full code. At the moment I'm just seeing the listview being populated by a long json-like string which is obviously wrong. I also don't seem to be hitting any breakpoints inside of the MainItemTemplate function so even though it's seeing it it's not being triggered for some reason.

     

     

    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll());
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
       
    
     var SubDataArray = [
            { title: "subtitle1", data: "data1" },
            { title: "subtitle2", data: "data2" },
            { title: "subtitle3", data: "data3" },
            { title: "subtitle4", data: "data4" },
            { title: "subtitle5", data: "data5" }
        ];
    
        var SubDataList = new WinJS.Binding.List(SubDataArray);
    
        var DataArray = [
            { title: "title1", data: SubDataList },
            { title: "title2", data: SubDataList },
            { title: "title3", data: SubDataList },
            { title: "title4", data: SubDataList },
            { title: "title5", data: SubDataList }
        ];
    
        var DataList = new WinJS.Binding.List(DataArray);
    
        var Members =
            {
                DataItem: DataList
            }
        WinJS.Namespace.define("Data", Members);
    
    
    
    	function MainItemTemplate(itemPromise) {
        return itemPromise.then(function (currentItem) {
        
    
            var result = document.createElement("div");
    
            var body = document.createElement("div");
          
    
            // Display title
            var title = document.createElement("div");
            title.innerText = currentItem.data.title;
            body.appendChild(title);
    
         
            // Display nested ListView
            var nestedListView = document.createElement("div");
            var listView = new WinJS.UI.ListView(nestedListView);
            listView.itemDataSource = currentItem.data.data.dataSource;
            listView.itemTemplate = document.getElementById("SubItemTemplate");
            body.appendChild(nestedListView);
    
            result.appendChild(body);
            return result;
        
        });
    }
    
     app.start();
    
    })();
    

    here is my HTML

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>App2</title>
    
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0.RC/js/ui.js"></script>
    
        <!-- App2 references -->
        <link href="/css/default.css" rel="stylesheet" />
        <script src="/js/default.js"></script>
    </head>
    <body>
     <div id="SubItemTemplate" data-win-control="WinJS.Binding.Template" >
            <p data-win-bind="textContent: title"></p>
            <p data-win-bind="textContent: data"></p>
        </div>
    
    	
     
           
        <div id="listView3" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: Data.DataItem.dataSource, itemTemplate: MainItemTemplate, layout: { type: WinJS.UI.GridLayout } }">
        </div>
    </body>
    </html>
    

    • Proposed as answer by Syllogism Wednesday, August 22, 2012 11:44 AM
    Thursday, August 16, 2012 3:26 PM
  • MainItemTemplate is defined inside an anonymous function so not visible to the HTML declarative processing.

    In your js code use WinJS.namespace.define() to expose the function to the HTML.

    WinJS.Namespace.define('myPage', {

            MainItemTemplate: MainItemTemplate
        });

    Then reference it in your control:

    itemTemplate:myPage.MainItemTemplate



    Jeff Sanders (MSFT)

    Thursday, August 16, 2012 6:53 PM
    Moderator
  • Thanks for the help.

    I also needed register the function using.

    WinJS.Utilities.markSupportedForProcessing(MainItemTemplate);

    Friday, August 17, 2012 9:20 AM
  • Thanks for making this post available. I'm currently facing the same issue and the solution proposed here actually works. I wonder how can we have two different templates in the sameWinJS.UI.ListView:

      • A template for the Master Data (let's say we have amounts and I want to format it up)
      • A template for a Details data (it actually works).

    Thanks.


    michaelfallas@gmail.com Michael Hidalgo Fallas

    Friday, August 31, 2012 4:57 PM
  • Hi Allen, 

    I did the same, but when i am coming back from snap view to full view, some of the item contains list view would not be loaded. At the same time, if i click that particular item then it will load the corresponding list view. I don't know whats wrong.

    1st Full View = Loading correctly,

    2nd Full to Snap View = Loading correctly,

    3rd Snap to Full View = Not Loading some of the item

    Please help to resolve this problem

    Thanks,

    Adhikesh

    Tuesday, May 07, 2013 8:05 AM