-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
template binding alters script template block HTML #2484
Comments
Can you describe why it's a problem that the script's content is cleared? |
Yes, my current issue is that the template is accessed from multiple modules at various times throughout my app's lifetime. The first time it gets accessed by the template binding it is cleared, so any subsequent attempts to retrieve it will return an empty string, causing elements for the templated type to have no content. |
If you're accessing the template from another template binding it should work just fine since Knockout keeps an internal cache of the template contents. But I'll look into improving this for the next release. |
This template is used by both the ko binding and in a more generic form where it becomes the basis for another HTML structure in pure javascript. Thanks. |
Leaving the innerHTML intact would result in unnecessary overhead, no? Maybe a util function that takes a template name and returns a cloned nodelist from the cache? |
Thought I'd chime in, I've been puzzled by this behaviour before and realized that it was by-design from source not long ago. I believe the template should not be cleared. |
Agreed. I'm not sure why it would seem desirable/acceptable to clear the template HTML. Here is the same example running with version 3.4.2: https://jsfiddle.net/r3sgw72j/ The template is left intact. |
In 3.5.0, we changed the way named templates are used. Instead of parsing the string contents every time the template is used, we parse it once and save the parsed nodes. We wanted to maintain backwards compatibility, though, with the ability to change the template contents at runtime. So that means we need to be able to know that the template contents have been updated. It seemed easy and efficient to simply be able to check that the template is non-empty. |
For clarification, it is only possible to alter the template prior to applyBindings being called in either 3.4.2 or 3.5. If you do this
Knockout does not update the DOM, so the template binding is still not dynamic in the way that the HTML binding is, for instance. Having it be only partially dynamic seems like the single most confusing outcome, from my perspective. Polymer made a Mutation Observer polyfill that goes back to IE9. I know that you would probably be loathe to consider it, but MO would make it possible to check for changes to the template and even easily make templates fully dynamic--eliminating the ambiguity. FWIW, IE 9 and 11 are the only versions with non-zero market share for years and Microsoft End of Life'd all but IE11 in 2016. |
@mbest I’d vote for a non-mutating alternative to template management. Perhaps tagging the template dom node is a good enough alternative to the non-empty check? |
I support immutable templates, as well. I do think the documentation needs to be explicit on this point, especially if the innerHTML hangs around. I also wonder if there ought not be a way to flush particular templates from the cache? In an arbitrarily complex application, it might not be desirable to hold all templates in memory at all times, especially with the potential for duplication between the DOM tree template and the cached NodeList(?) representation. |
I also vote for immutable templates, in can also add that in my case problem appeared due to fact that we have some generic code which is rendering components and it's taking use of ko.renderTemplate. After upgrade to 3.5.0 first call with script template removed content of template, and next usages of same templates result in error(as we share some templates between multiple components). |
@marcinkowal2015 Can you provide an example of this problem? Just based on my understanding of the Knockout code, I'm not able to understand a scenario that would reproduce what you're seeing. |
Knockout uses its |
Thanks for all of the feedback. I've uploaded a fix. |
I just tried an upgrade to 3.5 and noticed that using the 'template' binding with a named script template results in the script templates HTML being erased. See this fiddle: https://jsfiddle.net/rwL6pbmd/1/
It is a very simple example using a named template binding with a single data item. The issue is also present when using an array in foreach.
You'll notice that the script with id == 'tmpl-test' is originally populated with some dummy HTML, but that HTML gets erased after binding. Open your browser console to see the console.log messages.
The issue does not occur in 3.4.2 (my previous version).
The text was updated successfully, but these errors were encountered: