本文介绍了WinJS ListView 和模板绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图通过模板显示来自 JSON 请求的一些数据.数据有一些嵌套对象(数量不等),类似于:

data: "一些数据",嵌套:[{嵌套数据:foo",酒吧:foobar"}, ...],...

我已成功解析 JSON 并将其存储在 WinJS.Binding.List 对象中,并将结果绑定到模板.我遇到的问题实际上是在我的模板中显示嵌套的 JSON 数据.模板看起来像这样:

<div class="appTemplate"><div class="innerTemplate"><h1 data-win-bind="innerText: 数据"><h2 data-win-bind="innerText: 嵌套"></div></div>

当我运行这些程序时,模板的嵌套"部分只是一堆 [object Object] 而不是我想要显示的数据.

有什么方法可以创建模板以处理嵌套数据?定义模板函数会更容易吗?不知道在这里做什么...

解决方案

没有内置的方法可以做到这一点——唯一用于迭代数据的内置控件是列表视图.但是,您不能嵌套列表视图.

有两种方法可以解决这个问题,具体取决于您想要的结果:

1) 对嵌套数据进行字符串化:您可以通过编写一个 WinJS.Binding.converter 来完成此操作,它将您的数据数组转换为单个字符串值.示例

代码:

WinJS.Namespace.define("Examples.Converters", {嵌套数据转换器:WinJS.Binding.converter(函数(输入){//假设输入是数组变量结果 = "";input.forEach(函数(数据){结果 += data.nested_data + ", " + bar + ";";});结果结果;}),});

模板:

我推荐的解决方案是构建您的自己的 控件,该控件将获取您的数组(或 WinJS.Binding.List)并创建所需的元素/布局.我已经在我从事的一个项目中做到了这一点,而且非常简单.

示例模板:

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

现在,h2 将拥有该数据的单字符串版本.

2) 创建一个控件以丰富地显示数据:为此,您需要创建一个新的 WinJS 控件并在模板中使用它.

控制示例:

WinJS.Namespace.define("Examples.Controls", {压模:WinJS.Class.define(function(element, options) {WinJS.UI.setOptions(这个,选项);this.domElement = 元素;}, {domElement:空值_data:空,数据: {设置:函数(val){this._data = val;更新布局();}},更新布局:函数(){this.domElement.innerHTML = "";如果(!this._data){返回;}this._data.forEach(函数(项目){var el = document.createElement("div");el.textContent = "数据:" + item.nested_data + ", " + item.bar;this.domElement.appendChild(el);}.bind(this));}}),});

模板:

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

此控件可以扩展为呈现嵌套模板和其他项目.这完全是您想要变得多复杂的问题.

So I'm trying to display via a template some data from a JSON request. The data has some nested objects (of varying amounts) similar to this:

data: "Some data",
nested: [
 {
  nested_data: "foo",
  bar: "foobar"
  }, ...
],
...

I've managed to parse the JSON fine and store it in a WinJS.Binding.List object, and bound the result to a template. The problem I've got is actually displaying the nested JSON data in my template. The template looks something like this:

<div class="appTemplate">
 <div class="innerTemplate">
  <h1 data-win-bind="innerText: data">
  <h2 data-win-bind="innerText: nested">
 </div>
</div>

When I run the program those, the 'nested' part of the template is just a bunch of [object Object] rather than the data I want to display.

Is there some way I can create the template such that it can handle the nested data? Would it be easier to define a template function? Not sure what to do here...

解决方案

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.

这篇关于WinJS ListView 和模板绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 17:44