jsView - In contrast to #parent.data, ~root does not work in this case

StackOverflow https://stackoverflow.com/questions/16238589

  •  13-04-2022
  •  | 
  •  

Pregunta

Below is the example where #parent.data works and the first title can be changed. But when #parent.data is replaced with ~root, test2 tag is not rendered.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="js/jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="js/jsrender.js" type="text/javascript"></script>
    <script src="js/jquery.observable.js" type="text/javascript"></script>
    <script src="js/jquery.views.js" type="text/javascript"></script>

    <script id="test1Template" type="text/x-jsrender">
        <div>{^{>title}}{{:content}}</div>
        {{test2}}
        <h1>{^{>#parent.data.title}}</h1>
        {{/test2}}
    </script>

    <script id="myTemplate" type="text/x-jsrender">
        {^{test1 title='Test Title 1'}}
        {^{test1 title='Test Title 2'}}
        {{/test1}}
        {{/test1}}
    </script>

    <script type="text/javascript">
        $.views.tags({
            test1: function () {
                this.tagCtx.props.content = this.tagCtx.render();
                return $.templates.test1.render(this.tagCtx.props, undefined, this.tagCtx.view);
            },

            test2: function () {
                return this.tagCtx.render();
            }
        });

        $.templates({myTemplate: "#myTemplate",
            test1: "#test1Template"
        });

        $(function () {
            $.link.myTemplate('#container', {});

            $('#editTitle').click(function () {
                $.observable($.view('#container > div:first').data).setProperty('title', prompt());
            });
        });
    </script>
</head>
<body>
<span id="editTitle">EditTitle</span>

<div id="container"></div>
</body>
</html>
¿Fue útil?

Solución

~root is a reference to the data object or array you passed in initially - the top-level data. It is not the immediate parent data. In your case ~root will be the {} you passed in with the link.myTemplate() call.

Update added later: (Response to question in comment below about ~root)

From JsViews point of view, when any block tag content is rendered, it is also a 'view' - where a template is rendered against data. The views make up a hierarchy, and the top-level one is the one for which the data is exposed as ~root. So if you want to provide special short cut aliases for data at intermediate levels, you can do so, but that is for you to do. Declaratively that is done as in this example. In your case you are calling the intermediate level template render programmatically, so you can do the equivalent by providing a reference as a context variable:

return $.templates.test1.render(
    this.tagCtx.props, 
    {mydata: this.tagCtx.props}, 
    this.tagCtx.view);

Now you can write

<script id="test1Template" type="text/x-jsrender">
    <div>{^{>title}}{{:content}}</div>
    {{test2}}
    <h1>{^{>~mydata.title}}</h1>
    {{/test2}}
</script>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top