I use ajax to retrieve a partial HTML document to use as a Knockout template.
HTML:
<script type="text/html" id="LoadingTemplate">Loading...</script>
<script type="text/html" data-bind="attr: {'id': DynamicTemplateID}, html: ContentHTML></script>
<div class="main-page" data-bind="template: TemplateID"></div>
Script (partial):
self.TemplateID = ko.observable("LoadingTemplate");
self.DynamicTemplateID = ko.observable(GenerateUUID());
self.ContentHTML = ko.observable();
ko.computed(function () {
var url = self.ContentURL();
self.GetContent(url, function (html) {
self.ContentHTML(html);
self.TemplateID(self.DynamicTemplateID());
});
});
- Initially the
<div>will show: ‘Loading’ - The
idattribute of the dynamic template is set to the generated ID GetContent()performs an ajax call to retrieve the content- When the ajax call finishes the callback function is called
- The observable
ContentHTMLis updated with the html - The observable
TemplateIDis set to the generated ID - The
<div>is updated by ko
In Firefox this works like a charm, but IE8 throws an exception: Error: Unexpected call to method or property access. while updating the dummy <script> tag with the loaded template.
The error is throw by jQuery.html(). First elem.innerHTML = value; fails, which is catched then this.empty().append( value ) fails, which gives the exception.
Partial ‘stack trace’:
this.appendChild( elem ); => callback function in jquery.append (v1.7.2 line 5847)
jquery.domManip
jquery.append
jquery.html
ko.utils.setHtml
ko.bindingHandlers.html.update
ko.applyBindingsToNodeInternal
ko.dependentObservable.evaluateImmediate
What could be the problem? Is it there a (known) IE8 problem with updating <script> tags?
Is there another way to ‘store’ templates inside the html page for ko to use (I prefer to use the ko native templating!)?
I’ve solved it using this article on knockmeout.net:
Updated HTML (removed the dynamic
<script>tag):Updated script (appends the script tag after download of the template):
This is a little bit less the ko-way but works across all browsers.