Reputation: 41605
I'm quite new to Knockout and I'm getting a bit surprised of the way it displays things in the resultilng DOM.
I'm adding a 4 data
attributes in a row and one class, and I found out things start becoming to verbose when inspecting the resulting HTML markup to debug.
If I want to accomplish something like this:
<tr class="admin" data-user-id="10" data-user-email:'[email protected]' data-active="true">Alvaro</tr>
Ends up being too times longer in the resulting HTML markup:
<tr data-bind="text: name, css: type, attr:{ 'data-user-id': user_id, 'data-user-email': email, 'data-active': $root.isActive()}" class="admin" data-user-id="10" data-user-email='[email protected]' data-active="true">Alvaro</tr>
It makes inspecting the DOM a bit more difficult as many hidden data (or logic) is being displayed on the resulting markup.
Is this normal in these kind of frameworks ? (ember.js, angular.js...) or it is something just something particular from knockout.js?
Is there any way to prevent this kind of "duplicating" ?
Upvotes: 1
Views: 142
Reputation: 16688
If you're concerned about the data-bind
attribute persisting in the HTML after binding, you can remove that attribute using a custom binding provider. Here's one I wrote to do that: https://stackoverflow.com/a/23620576/1287183
Upvotes: 2
Reputation: 1672
Building on Jeff Mercado's comment, if you created a custom binding that looked like this:
ko.bindingHandlers.myCustomBinding = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $data = ko.unwrap(valueAccessor());
element.setAttribute('data-user-id', $data.user_id);
element.setAttribute('data-user-email', $data.email);
element.setAttribute('data-active', ko.unwrap(bindingContext.$parent.isActive));
}
}
You could apply it to your element like this:
<tr data-bind="myCustomBinding: $data"></tr>
And the resulting HTML when you inspect the DOM would appear like this:
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="[email protected]" data-active="true"></tr>
Less chatty and now you have a reusable binding.
Also, you don't have to pass $data
into your custom binding as I did in the example above. Instead, you could reference bindingContext.$data
within the custom binding init
function rather than unwrapping the valueAccessor
. If you do that then you can pass anything over to your custom binding including an empty string since the valueAccessor
will not be used in your custom binding. This would shorten up your HTML even more since it would start off looking like this instead: <tr data-bind="myCustomBinding: ''"></tr>
Upvotes: 3