locked
Rendering an external template before an internal one sets the 'textContent' data-binding to 'undefined' RRS feed

  • Question

  • When I try to render a regular template (a template defined in the HTML page) after I render a template from another HTML file, the 'textContent' data-binding is rendered as 'undefined'.

    If I reverse the render order, everything renders fine.

    Why is that and how do I fix it so it also renders the 'textContent' binding?

    Below is some sample code to reproduce the problem.
    To reproduce the issue; Create a new blank Windows 8 Metro app, override the default.html and default.js content with the HTML and JS code from below. Create a new HTML file at root level in the application. Name the file "templateOne.html" and insert the HTML code from the "templateOne" code block below.

    If you run the application you should see that the textContent is 'undefined'.

    Replace the content of 'default.html' with this:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>App17</title>
    
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0.RC/js/ui.js"></script>
    
        <!-- App17 references -->
        <link href="/css/default.css" rel="stylesheet" />
        <script src="/js/default.js"></script>
    </head>
    <body>
    
        <div id="content"></div>
    
        <div id="templateTwo" data-win-control="WinJS.Binding.Template">
            <p>TemplateTwo text here: <span data-win-bind="textContent: text; style.color: color"></span></p>
        </div>
    
    </body>
    </html>

    Replace the content of 'default.js' with this:

    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        WinJS.UI.Pages.define("default.html", {
            ready: function (element, options) {
    
                // Render target container.
                var renderTarget = document.getElementById("content");
    
                // Render 'templateOne'.
                WinJS.Binding.Template.render("templateOne.html", {}, renderTarget);
                
                // Render 'templateTwo'.
                templateTwo.winControl.render({ text: "This was rendered with 'templateTwo'.", color: "red" }, renderTarget);
            }
        });
    
    
        app.onactivated = function (args) {
            args.setPromise(WinJS.UI.processAll());
        };
    
        app.start();
    })();

    This is the content for the 'templateOne.html' file:

    <p>
        This is templateOne.
    </p>

    Thursday, July 19, 2012 12:57 PM

Answers

  • I found the solution to my problem:

    // Render target container.
    var renderTarget = document.getElementById("content");
    
    // Render 'templateOne'.
    WinJS.Binding.Template.render("templateOne.html", {}, renderTarget).then(function () {
    	// Render 'templateTwo'.
            templateTwo.winControl.render({ text: "This was rendered with 'templateTwo'.", color: "red" }, renderTarget);
    });


    • Marked as answer by Aratys Wednesday, July 25, 2012 7:59 AM
    Wednesday, July 25, 2012 7:59 AM

All replies

  • hi

    I find the difference is the renderTarget.

    You can add a watch to the renderTarget when it can be right display 

    the class name =from"win-template " to "win-template win-loading"

    When it can't display the text 

    the class name=from"win-template  win-loading" to "win-template"

    So I think maybe the node's loading data have been covered by template.

    The solution is reverse the sequence as you said.

    Friday, July 20, 2012 9:46 AM
  • I am not sure what you mean. How will changing the class names do any difference to how things are rendered?

    A working example would be greatly appreciated.

    The solution is not to reverse the order; It is just to show there is something going on after 'templateOne' is rendered that causes the 'textContent' property to not be binded when rendering 'templateTwo'.

    Friday, July 20, 2012 10:05 AM
  • I found the solution to my problem:

    // Render target container.
    var renderTarget = document.getElementById("content");
    
    // Render 'templateOne'.
    WinJS.Binding.Template.render("templateOne.html", {}, renderTarget).then(function () {
    	// Render 'templateTwo'.
            templateTwo.winControl.render({ text: "This was rendered with 'templateTwo'.", color: "red" }, renderTarget);
    });


    • Marked as answer by Aratys Wednesday, July 25, 2012 7:59 AM
    Wednesday, July 25, 2012 7:59 AM