Answered by:
Problems binding listviews and individual elements

Question
-
Hello everyone,
I'm experiencing some problems when binding html tags and listviews. The html tags after the list view are not bind...
This only happens if the listview dataSource is set to a property of the object of the data-win-bindsource...
It is a bit complicated to explain so I'll just paste the code here see if anyone can help me figure out what is going on and if this is the expected behavior:
HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>BindTests</title> <!-- WinJS references --> <link rel="stylesheet" href="/winjs/css/ui-dark.css" /> <script src="/winjs/js/base.js"></script> <script src="/winjs/js/res.js"></script> <script src="/winjs/js/ui.js"></script> <script src="/winjs/js/controls.js"></script> <script src="/winjs/js/binding.js"></script> <script src="/winjs/js/wwaapp.js"></script> <script src="/winjs/js/animations.js" type="text/javascript"></script> <script src="/winjs/js/uicollections.js" type="text/javascript"></script> <!-- BindTests references --> <link rel="stylesheet" href="/css/default.css" /> <script src="/js/default.js"></script> </head> <body> <div> <h1 data-win-bindsource="Source.item" data-win-bind="innerText: description"> This should be Item Description</h1> <div id="template" data-win-control="WinJS.Binding.Template"> <div> <div data-win-bind="innerText: id"> </div> <div data-win-bind="innerText: name"> </div> </div> </div> <div data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:template,layout:{type:WinJS.UI.ListLayout}}"> </div> <div> <h2 data-win-bind="innerText:id"> This should be Item id</h2> </div> </div> </body> </html>
JavaScript(function () { 'use strict'; WinJS.Application.onmainwindowactivated = function (e) { if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { WinJS.UI.processAll().then(function () { WinJS.Binding.processAll(); }); } } WinJS.Application.start(); WinJS.Namespace.define('Source', { item: { id: 'Item id', description: 'Item description', list: [{ id: 1, name: 'Name 1' }, { id: 2, name: 'Name 2' }, { id: 3, name: 'Name 3' }], } }); })();
The bind after the list (innerText:id) doesn't work, but as soon as I remove the list (or I edit the template and remove all the data-win-bind) it works.Even if I try to set again the data-win-bindsource in that element doesn't work :(
Any tip of what is going on?
Thanks!!
Sunday, November 20, 2011 3:22 AM
Answers
-
Since the binding.processAll() handles all binds in the entrie document body, and it handles the ListView/Template binding. But yhe control of Template or ListView cannot pass the condiftion inContainer in binding.js and it returns True, so the bindings after them cannot be handled during the processAll method. You have to call the
WinJS.Binding.processAll( /*specific element you want to bind*/ );
to handle the binding on the h2 element.Code snippet:
...... <div id="listView" data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:itemtemplate,layout:{type:WinJS.UI.ListLayout}}"> </div> <div> <h2 id="itemid" data-win-bindsource="Source.item" data-win-bind="innerText: id"> This should be Item id</h2> </div>
Js:
WinJS.UI.processAll().then(function () { WinJS.Binding.processAll(); WinJS.Binding.processAll(document.getElementById("itemid")); });
or you could declare the different parts for the h1 and the h2, and you just could processAll the "part1" and the "part2". For example:HTML: <body> <div id="itemtemplate" data-win-control="WinJS.Binding.Template"> <div> <div data-win-bind="innerText: id"> </div> <div data-win-bind="innerText: name"> </div> </div> </div> <div id="part1" data-win-bindsource="Source.item"> <h1 data-win-bind="innerText: description"> This should be Item Description: </h1> <div data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:itemtemplate,layout:{type:WinJS.UI.ListLayout}}"> </div> </div> <div id="part2" data-win-bindsource="Source.item"> <h2 data-win-bind="innerText: id"> This should be Item id</h2> <div data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:itemtemplate,layout:{type:WinJS.UI.ListLayout}}"> </div> </div> </body>
Js:WinJS.UI.processAll().then(function () { WinJS.Binding.processAll(document.getElementById("part1")); WinJS.Binding.processAll(document.getElementById("part2")); });
P.S. you could check the code of the processAll method in the binding.js: line 1024 declarativeBindImpl function.
Sincerely,
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- Edited by Jie Bao Monday, November 21, 2011 9:51 AM
- Marked as answer by Anton Molleda Monday, November 21, 2011 9:12 PM
Monday, November 21, 2011 9:34 AM
All replies
-
Since the binding.processAll() handles all binds in the entrie document body, and it handles the ListView/Template binding. But yhe control of Template or ListView cannot pass the condiftion inContainer in binding.js and it returns True, so the bindings after them cannot be handled during the processAll method. You have to call the
WinJS.Binding.processAll( /*specific element you want to bind*/ );
to handle the binding on the h2 element.Code snippet:
...... <div id="listView" data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:itemtemplate,layout:{type:WinJS.UI.ListLayout}}"> </div> <div> <h2 id="itemid" data-win-bindsource="Source.item" data-win-bind="innerText: id"> This should be Item id</h2> </div>
Js:
WinJS.UI.processAll().then(function () { WinJS.Binding.processAll(); WinJS.Binding.processAll(document.getElementById("itemid")); });
or you could declare the different parts for the h1 and the h2, and you just could processAll the "part1" and the "part2". For example:HTML: <body> <div id="itemtemplate" data-win-control="WinJS.Binding.Template"> <div> <div data-win-bind="innerText: id"> </div> <div data-win-bind="innerText: name"> </div> </div> </div> <div id="part1" data-win-bindsource="Source.item"> <h1 data-win-bind="innerText: description"> This should be Item Description: </h1> <div data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:itemtemplate,layout:{type:WinJS.UI.ListLayout}}"> </div> </div> <div id="part2" data-win-bindsource="Source.item"> <h2 data-win-bind="innerText: id"> This should be Item id</h2> <div data-win-control="WinJS.UI.ListView" data-win-options="{dataSource:Source.item.list,itemRenderer:itemtemplate,layout:{type:WinJS.UI.ListLayout}}"> </div> </div> </body>
Js:WinJS.UI.processAll().then(function () { WinJS.Binding.processAll(document.getElementById("part1")); WinJS.Binding.processAll(document.getElementById("part2")); });
P.S. you could check the code of the processAll method in the binding.js: line 1024 declarativeBindImpl function.
Sincerely,
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- Edited by Jie Bao Monday, November 21, 2011 9:51 AM
- Marked as answer by Anton Molleda Monday, November 21, 2011 9:12 PM
Monday, November 21, 2011 9:34 AM -
Ok, I get the result. In the line 1050 in the binding.js, the condition:
if (inContainer(baseElement, WinJS.UI.getControl(element), element)) { return; }
will return true if we want to process the binding of the ListView or the Template elements, so the function will return and does not handle the binding in the element after the ListView.Template constructor.isDeclarativeControlContainer is always true, you could get the declaration from the line 878 in the binding.js file.
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- Edited by Jie Bao Monday, November 21, 2011 9:55 AM
Monday, November 21, 2011 9:45 AM -
So I assume this is not the expected behavior for the final version, right?
Anyways, I end up doing doing a query to look for [data-win-bindsource] and then a processAll for each element in the collection.
Thanks!
Monday, November 21, 2011 9:12 PM