Knockout.js 淘汰赛和#xBF;绑定名称是否可以是动态的(变量)?

Knockout.js 淘汰赛和#xBF;绑定名称是否可以是动态的(变量)?,knockout.js,Knockout.js,正如knockout官方文档()所述,绑定有名称和值: 这里的关键是,我的viewmodel的道具取决于模型对象的特定子类型,因此我不想为每个子类型(太多)实现自定义HTML模板。现在,我的模板看起来像: //HTML <div data-bind='foreach: { data: metaProps }'> <!-- ko if: binding == 'url' --> <span data-bind="url: $parent[n

正如knockout官方文档()所述,绑定有名称和值:

这里的关键是,我的viewmodel的道具取决于模型对象的特定子类型,因此我不想为每个子类型(太多)实现自定义HTML模板。现在,我的模板看起来像:

//HTML      
<div data-bind='foreach: { data: metaProps }'>
  <!-- ko if: binding == 'url' -->  
    <span data-bind="url: $parent[name]">   
  <!-- /ko -->                                   
  <!-- ko if: binding == 'isbn' --> 
    <span data-bind="isbn: $parent[name]">  
  <!-- /ko -->              
  <!-- ko if: binding == 'text' --> 
    <span data-bind="text: $parent[name]">  
  <!-- /ko -->  
  ...
</div>
//HTML
...
我的目标是将html简化为:

<div data-bind='foreach: { data: metaProps }'> 
    <span data-bind="binding: $parent[name]">     
</div>

不确定这是否可以解决您的全部问题,但您可以动态生成html

函数VM(){
var self=这个;
self.metaProps=[
{name:'url1',val:'},
{name:'text1',val:'text'},
{name:'isbn1',val:'isbn'},
]
}
应用绑定(新VM())


有一个(遗憾的是没有文档记录)实用程序函数
applybindingstoode
,它允许您创建一个自定义绑定,该绑定可能会实现您想要的功能:

ko.bindingHandlers.dynamicBinding = {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var bindings = {};
        var bindingData = valueAccessor();
        bindings[bindingData['binding']] = bindingContext.$data[bindingData['name']];
        ko.applyBindingsToNode(element, bindings, bindingContext);
    }
};
这样称呼它:


编辑: 我喜欢@Tomalak建议的组件思想,因为它允许标记具有更大的灵活性。举一个小例子来说明:

要注册组件,请执行以下操作:

ko.components.register('isbn', {
    viewModel: function(params) {
        this.content = params.content;
    },
    template: '<span data-bind="text: content"></span>'
});

ko.components.register('url', {
    viewModel: function(params) {
        this.content = params.content;
    },
    template: '<a data-bind="attr: { href: content }, text: content"></a>'
});
然后调用
组件
绑定来加载组件

<div data-bind="foreach: { data: metaProps, as: 'metaProp' }">
    <!-- ko component: { name: metaProp.component, params: { content: metaProp.content } } -->
    <!-- /ko -->
</div>

我会与之合作,因为:

  • 它在格式和数据处理方面提供了更大的灵活性:您不必为所有项目使用相同的
    ,每个模板都可以不同
  • 它是可重用的,即您可以在视图中的任何位置一致地呈现
    isbn
    。它甚至可以完全取代ISBNs对自定义绑定处理程序的需求
  • 它产生了一个清晰直观的视图和模型
//作为真正的“isbn”处理程序的模型,让我们只使用“text”
ko.bindingHandlers.isbn=ko.bindingHandlers.text;
ko.applyBindings({
元支柱:[
{type:'text',value:'Some sample text'},
{类型:'isbn',值:'978-1491914311'},
{类型:'url',值:'https://knockoutjs.com/documentation/introduction.html,文本:“淘汰文档”}
]
});
.isbn{font-family:monospace;}

ko.components.register('isbn', {
    viewModel: function(params) {
        this.content = params.content;
    },
    template: '<span data-bind="text: content"></span>'
});

ko.components.register('url', {
    viewModel: function(params) {
        this.content = params.content;
    },
    template: '<a data-bind="attr: { href: content }, text: content"></a>'
});
var metaProps = [   
  { content: this.url1, component: 'url' },
  { content: this.text1, component: 'text' },
  { content: this.isbn1, component: 'isbn' },
...
]
<div data-bind="foreach: { data: metaProps, as: 'metaProp' }">
    <!-- ko component: { name: metaProp.component, params: { content: metaProp.content } } -->
    <!-- /ko -->
</div>