Reputation: 18445
I have a chat room style application and each entry is processed on the client once it is received and then some html is generated to display it. As certain messages will have tooltips and other bits of data embedded within them which use knockout bindings to display.
Now after looking over all the posts around this the answers to this problem seem to be:
The first one is not feasible as you only create the elements as the chat comes in from the server, so the second option seems the only way to do it, however this would require calling for each chat message that comes in. A lot of people say that ko.applyBindings can incur significant overheads, however I think they mean if you were to call it upon all elements rather than just targeting specific ones.
Just so that everyone is on the same page, here is the basic snippet of the view around the area that matters:
<!-- ko foreach: {data: ChatRoom.Entries, afterRender: ChatEntryRendered } -->
<div class="entry-content" data-bind="html: ProcessedContent"></div>
<!-- /ko -->
Ignoring the bits around that, it will basically loop around each entry, add a div which will contain html which will contain bindings which need knockout goodness applied. So for example the ProcessedContent
could look something like:
<span>Some content with a <span data-bind="tooltip: 'Some Content Here'">DYNAMIC</span> bit of <span class="special-text">Content</span></span>
So this above html would not currently be processed by the foreach as it is dynamically applied to the page, and before everyone starts freaking out about injecting html into the views, the server does not send down any markup, it just sends down a string with a load of tokens which the client converts into html. Also without muddying the waters too much, in this scenario the ChatRoom.Entries
object is culled every now and again so it will fluctuate from 0-200 (usually 100-200) entries at any given time and the rest of the chat entries are cached in local storage, just so there are never more than about 150 bound Entries to the view at any given time.
Here is a jsfiddle showing the issue in a practical example.
Upvotes: 1
Views: 1917
Reputation: 16688
The main reason that the html
binding doesn't bind the inserted html is because it can be unsafe. But if you know it's safe, you can use a custom binding that does bind the contents. Here's an example from another SO question: https://stackoverflow.com/a/17756777/1287183
Fiddle: http://jsfiddle.net/Mps4Q/9/
Upvotes: 1