devinwl
devinwl

Reputation: 85

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

Upvotes: 0

Views: 1152

Answers (3)

Geek Devigner
Geek Devigner

Reputation: 369

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.

Upvotes: 0

Dominic Hopton
Dominic Hopton

Reputation: 7292

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.

Upvotes: 4

siger
siger

Reputation: 3162

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

Upvotes: 0

Related Questions