【问题标题】:Dynamically constructed knockout component template based on component params基于组件参数动态构建的剔除组件模板
【发布时间】:2017-04-17 19:32:36
【问题描述】:

我目前正在使用 knockout.js 作为我正在开发的应用程序的一部分。我需要实现一个淘汰组件,其中包含一个无序列表,其列表项根据组件参数的不同而有所不同。

注册组件的基本代码如下:

ko.components.register('data-display', {
    viewModel: function(name, obj, vis) {
        var self = this;
        for (var index in obj) {
            self[index] = obj[index];
        }
    },
    template: //Template lives here
});

function templateConstructor(name, obj, vis) {
    var template = '<h2>' + name + '</h2>\r\n';
    template += '<ul>\r\n';
    for (var index in obj) {
        var kvInfo = getKVInfo(vis, index); 
        if (kvInfo) {
            template += '<li><strong>' + kvInfo + '</strong><span data-bind="text: ' + index + '"></span></li>\r\n';
        }
    }
    template += '</ul>\r\n';
    return template;
}

function getKVInfo(vis, index) {
    for(var key in vis) {
        if (key == index) {
            return vis[key];
        }
    }
    return False;
}

objnamevis 的值将采用以下形式:

var name = "Information"
var obj = {foo: ko.observable('bar'), bar: ko.observable('foo'), ta: ko.observable('da')}
var vis = {foo: 'Foo Info: ', bar: 'Bar Info: '}

这个想法是组件将有一个包含名称的标题,然后从 obj 显示的数据被 vis 屏蔽。即:在上述情况下,只有 foobar 元素在组件中可见。 我要解决的问题是如何从 HTML 组件声明中获取参数并将它们传递给模板和视图模型,这样我就可以使用 html:

<data-display params="name: name, obj: obj, vis: vis"></data-display>

并获得这个结果:

<h2>Information</h2>
<ul>
    <li><strong>Foo Info: </strong><span data-bind="text: foo"></span></li>
    <li><strong>Bar Info: </strong><span data-bind="text: bar"></span></li>
</ul>

【问题讨论】:

    标签: javascript knockout.js components


    【解决方案1】:

    没有内置支持组件具有动态创建的模板。但是组件可以定义一个createViewModel 属性而不是视图模型构造函数,它可以访问元素。这是一个例子:

    ko.components.register('data-display', {
        viewModel: {
            createViewModel: function(params, componentInfo) {
                var componentVM = new viewModelConstructor(params);
                var template = templateConstructor(componentVM);
                ko.virtualElements.setDomNodeChildren(componentInfo.element, ko.utils.parseHtmlFragment(template));
                return componentVM;
            }
        },
        template: []
    });
    

    或者您可以使用我在https://github.com/knockout/knockout/issues/1458#issuecomment-154578662 发布的通用组件加载器

    【讨论】:

    • 工作就像一个绝对的魅力。感谢您的帮助。
    猜你喜欢
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2021-09-29
    • 1970-01-01
    • 2020-04-11
    • 2020-09-16
    • 2019-07-28
    相关资源
    最近更新 更多