WinJS ListView and Template Binding

雨燕双飞 提交于 2019-11-29 12:58:52

There is no built in way to do this -- the only built in control for iterating over data is the List View. However, you cannot nest List Views.

There are two ways to solve this problem, depending on your desired outcome:

1) Stringifying the nested data: You can do this by writing a WinJS.Binding.converter that will convert your array of data into a single string value. Example

Code:

WinJS.Namespace.define("Examples.Converters", {
    nestedDataConverter: WinJS.Binding.converter(function(input) {
        // Assume input is array
        var result = "";
        input.forEach(function(data) {
            result += data.nested_data + ", " + bar + ";";
        });

        result result;
    }),
});

Template:

My recommended solution would to build your own control that will take your array (or WinJS.Binding.List) and create the elements / layouts needed. I have done this in a project I work on, and it's super simple.

Example Template:

<div class="appTemplate" data-win-control="WinJS.Binding.Template">
  <div class="innerTemplate">
    <h1 data-win-bind="innerText: data">
    <h2 data-win-bind="innerText: nested Examples.Converters.nestedDataConverter">
  </div>
</div>

Now, the h2 will have the single-string version of that data.

2) Create a control to display the data richly: To do this you need to create a new WinJS control and use it in your template.

Control example:

WinJS.Namespace.define("Examples.Controls", {
    Stamper: WinJS.Class.define(function(element, options) {
        WinJS.UI.setOptions(this, options);
        this.domElement = element;
    }, {
        domElement: nullm
        _data: null,
        data: {
            set: function(val) {
                this._data = val;
                updateLayout();
            }
        },
        updateLayout: function() {
            this.domElement.innerHTML = "";
            if(!this._data) {
                return;
            }

            this._data.forEach(function(item) {
                var el = document.createElement("div");
                el.textContent = "Data: " + item.nested_data + ", " + item.bar;
                this.domElement.appendChild(el);
            }.bind(this));
        }
    }),
});

Template:

<div class="appTemplate" data-win-control="WinJS.Binding.Template">
  <div class="innerTemplate">
    <h1 data-win-bind="innerText: data"></h1>
    <div data-win-control="Examples.Controls.Stamper"
         data-win-bind="winControl.data: nested"></div>
  </div>
</div>

This control can be extended to render nested templates, and other items. It's all a question of how complex you want to get.

Try data-win-bind="innerText: nested.nested_data"

This will be much easier with a template function.

The built in bindable templates are great for templates that are logicless, but fall short when you need the template to make decisions based on data values, and in your case, deeper properties.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!