0

I have a problem rendering a tree object in JavaScript when using IE8. In order to write a hierarchy in an HTML page, I need to use a knockout template to recursively render the tree object.

I am using knockout components to render the final result using requirejs and require.text

The component is working fine in all browsers except for IE8. I know I should not be using IE8, but this is an intranet site for a company that cannot upgrade all browsers easily right now. I simplified the code to only render a list of numbers in a plain list using the template.

Here is the ViewModel in test.vm.js:

define(['knockout'], function(ko) {

function TestViewModel() {
    var self = this;
    self.Title = "Example";
    self.List = [
        { Name: "1" },
        { Name: "2" },
        { Name: "3" },
        { Name: "4" }
    ];
}

return TestViewModel;
});

Here is the View in test.view.js:

<script type="text/html" id="testTemplate">
<li data-bind="text: Name"></li>
</script>

<div>
<div data-bind="text: Title"></div>
<ul data-bind="template: {name: 'testTemplate', foreach: List}">
</ul>
</div>  

And finally, the HTML page calling the component:

<html>
<head>
    <meta charset="utf-8" />
    <title>App</title>
    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/require.js"></script>
</head>
<body>


<script type="text/javascript">

    require.config({
        baseUrl: "/",
        paths: {
            'knockout': 'Scripts/knockout-3.2.0',
            'text': 'Scripts/require.text'
        }
    });


    $(document).ready(function () {
        require(['knockout'], function (ko) {
            ko.applyBindings();
        });
    });

    require(['knockout'], function (ko) {
        ko.components.register('TestComponent', {
            viewModel: { require: 'Scripts/test.vm' },
            template: { require: 'text!Scripts/test.view.js' }
        });
    });
</script>

<!-- ko component: { name: "TestComponent" } -->
<!-- /ko -->

</body>
</html>

The main difference I can see browsing the DOM is that the template is rendered in other browsers completely

<script id="testTemplate" type="text/html">
<li data-bind="text: Name"></li>
</script>

while in IE8 is empty

<SCRIPT id=testTemplate type=text/html __ko__1453323521948="ko12"></SCRIPT>

If I put the template "testTemplate" outside the view file and directly in the HTML page, the component start to work. The component is not working just because the template is empty. Placing the "testTemplate" in the HTML is a partial solution but I need to find why it is not working when is placed inside the view file.

UPDATE: I simplified the scenario. Apparently is some bug in the "template" parameter in component registration. If the template is enclosed in script tags, the content is ignored and not rendered in the page. If I decide to change it to use <template> tags, component tries to resolve data bindings inside the template and shows an error. Template tags are supposed to be ignored in bindings but the component does not ignore the tags. I tried with a temporal hack using the last tag I read is configured to be ignored by templates, by enclosing the template in textarea tags and placing display:none. Now the contents are rendered in all browsers but I don't like this solution.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Miguel
  • 119
  • 4

1 Answers1

0

I work for a company that still uses Windows XP so I'm limited to IE8 too. We are successfully using knockout component templates with require.js and the text plugin.

Re. "If the template is enclosed in script tags, the content is ignored and not rendered in the page":

We have our templates inside HTML files, and use the !strip suffix to remove the wrapping HTML & body tags. This successfully loads the templates and also gives better editor support as the file extension is correct for editing markup.