Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access parent data properties in JsRender nested templates

http://jsfiddle.net/tQnVt/621/

This fiddle illustrates my problem.

Say I am binding a JSON onto view with the help of jsrender templates.

var vm = {
    foo: {color: "red",otherObjectToMatch:"object"},
    testData: [{color: "red"}, {color: "yellow"}, {color: "blue"}]
};

Object vm has 2 properties- 1) a plain object 2) array of objects.

Template-

<script id="template" type="text/x-jsrender">
    <p>
    {{:foo.color}}
    </p>
    <ul>
    {{for testData}}
        <li>index: {{>color}}</li>
    {{/for}}
    </ul>
</script>

I want to match from plain object #1 by its property where if its property color matches with the property in loop then will apply some class.

I tried-

 <p>
    {{:foo.color}}
    </p>
    <ul>
    {{for testData}}
       {{if foo.color=={{>color}} }}
         <li class='match'>index: {{>color}}</li>
       {{else}}
         <li>index: {{>color}}</li>
       {{/if}}
    {{/for}}
    </ul>

This is a failed try. I can't find how to match with other objects in jsrender.

like image 246
Manoz Avatar asked Jan 22 '16 08:01

Manoz


1 Answers

You need to write

{{if xxx.foo.color===color}}

where xxx is the parent data - in your case the vm you passed in as root data.

(It's all about the 'view hierarchy' - see: http://www.jsviews.com/#views. See also the specific topic Accessing parent data)

Here are several different ways to get to the data on the parent view:

Access ~root which is a shortcut helper for the root data:

{{for testData}}
   {{if ~root.foo.color===color}} 
     <li class='match'>index: {{>color}} (match)</li>
   {{else}}
     <li>index: {{>color}}</li>
   {{/if}}
{{/for}}

Create a contextual template parameter ~foo to pass the foo property from parent data through to the nested template contexts:

{{for testData ~foo=foo}}
   {{if ~foo.color===color}}
     <li class='match'>index: {{>color}} (match)</li>
   {{else}}
     <li>index: {{>color}}</li>
   {{/if}}
{{/for}}

Step up through the parent view objects, and get the data view:

{{for testData}}
   {{if #parent.parent.data.foo.color===color}}
     <li class='match'>index: {{>color}} (match)</li>
   {{else}}
     <li>index: {{>color}}</li>
   {{/if}}
{{/for}}

Use the view.get() helper to find the parent of view of type "data"

{{for testData}}
   {{if #get("data").data.foo.color===color}}
     <li class='match'>index: {{>color}} (match)</li>
   {{else}}
     <li>index: {{>color}}</li>
   {{/if}}
{{/for}}

I added all of them to your jsfiddle: http://jsfiddle.net/tQnVt/625/

See also this related reply: https://stackoverflow.com/a/34441881/1054484

like image 177
BorisMoore Avatar answered Oct 28 '22 15:10

BorisMoore