Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
918 views
in Technique[技术] by (71.8m points)

windows 8 - WinJS ListView and Template Binding

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...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...