Javascript Knockout.js太冗长了?

Javascript Knockout.js太冗长了?,javascript,knockout.js,knockout-3.0,Javascript,Knockout.js,Knockout 3.0,我对Knockout很陌生,我对它在ResultingDOM中显示东西的方式感到有点惊讶 我在一行和一个类中添加了4data属性,我发现在检查要调试的结果HTML标记时,事情开始变得冗长 如果我想完成这样的事情: <tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr> ko.bindingHandlers.myCustomBind

我对Knockout很陌生,我对它在ResultingDOM中显示东西的方式感到有点惊讶

我在一行和一个类中添加了4
data
属性,我发现在检查要调试的结果HTML标记时,事情开始变得冗长

如果我想完成这样的事情:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>
阿尔瓦罗 最终在生成的HTML标记中的时间过长:

<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='demo@demo.com' data-active="true">Alvaro</tr>
阿尔瓦罗 由于在结果标记上显示了许多隐藏的数据(或逻辑),因此检查DOM有点困难

这在这种框架中正常吗?(ember.js,angular.js…)或者它只是来自knockout.js的一些特殊内容


有没有办法防止这种“复制”?

基于Jeff Mercado的评论,如果您创建了一个如下所示的自定义绑定:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>
可以将其应用于元素,如下所示:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>

检查DOM时生成的HTML如下所示:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>

少了闲聊,现在您有了一个可重用的绑定


此外,您不必像我在上面的示例中那样将
$data
传递到自定义绑定中。相反,您可以在自定义绑定
init
函数中引用
bindingContext.$data
,而不是展开
valueAccessor
。如果这样做,则可以将任何内容传递给自定义绑定,包括空字符串,因为在自定义绑定中不会使用
valueAccessor
。这将进一步缩短您的HTML,因为它一开始看起来是这样的:

基于Jeff Mercado的评论,如果您创建了一个如下所示的自定义绑定:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>
可以将其应用于元素,如下所示:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>

检查DOM时生成的HTML如下所示:

<tr class="admin" data-user-id="10" data-user-email:'demo@demo.com' data-active="true">Alvaro</tr>
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));
    }
}
<tr data-bind="myCustomBinding: $data"></tr>
<tr data-bind="myCustomBinding: $data" data-user-id="10" data-user-email="demo@demo.com" data-active="true"></tr>

少了闲聊,现在您有了一个可重用的绑定


此外,您不必像我在上面的示例中那样将
$data
传递到自定义绑定中。相反,您可以在自定义绑定
init
函数中引用
bindingContext.$data
,而不是展开
valueAccessor
。如果这样做,则可以将任何内容传递给自定义绑定,包括空字符串,因为在自定义绑定中不会使用
valueAccessor
。这将进一步缩短您的HTML,因为它一开始看起来是这样的:

如果您担心绑定后HTML中持久存在的
数据绑定
属性,可以使用自定义绑定提供程序删除该属性。我写了一个这样做的例子:

如果您关心绑定后HTML中持久化的
数据绑定
属性,可以使用自定义绑定提供程序删除该属性。我写了一篇文章就是为了做到这一点:

你总是可以选择创建一个自定义绑定来隐藏一些配置。这在SPA中很常见,例如角度绑定等。渲染后,它往往会显示绑定+渲染内容,这会让您觉得有点冗长。您始终可以选择创建自定义绑定来隐藏一些配置。这在SPA中非常常见,例如角度等。渲染后,它往往会显示绑定+渲染内容,这会让人觉得有点冗长。感谢您的解释,您能否提供一个示例,说明您在
myCustomBinding
中不传递
$data
变量,而不是展开
valueAccessor()
只需使用
bindingContext
上的
$data
属性,例如
bindingContext.$data.user\u id
。感谢您的解释,您能否在
myCustomBinding
中提供一个不传递
$data
变量的示例,而不是展开
valueAccessor()
只需使用
bindingContext
上的
$data
属性,例如
bindingContext.$data.user\u id
。有趣的解决方案!在渲染和删除
数据绑定
属性之间是否有任何延迟?或者它在渲染之前执行。有趣的解决方案!在渲染和删除
数据绑定
属性之间是否有任何延迟?或者在渲染之前执行该操作。