2个模板中的knockout observablearray

时间:2016-12-15 10:25:20

标签: javascript templates knockout.js

我有2个observabeleArrays。一个包含我可以选择的所有可能类型,另一个包含所有选择的类型。第一个模板显示所有可能的类型,另一个模板显示所有选定的类型。如果我单击第一个模板之一(所有可能性),它将被添加到所选的模板列表中,并显示在第二个模板中。如果我在第二个模板中单击选定的一个,则会从那里删除它。此外,在第一个模板中,我想显示对所选对象的检查。大多数东西都有效,但如果我通过第二个模板删除对象,则检查不会更新。我试图将我的代码减少到重要的部分,我希望它更有意义,并且没有任何错误: 任何人都知道如何解决它,所以我的检查显示正确吗?它取决于每个对象的Selected值,它正确更新,但视图不会更改。

//main html
//...
            <div data-bind="component: {
                    name: 'selector-component',
                    params: {
                        selected: vm.selected,
                        types: vm.types,
                    }
                }">
            </div>
            <div data-bind="component: {
                    name: 'selected-component',
                    params: {
                        selected: vm.selected,
                    }
                }">
            </div>
//...
<script type="text/javascript">

    vm.selected = ko.observableArray([]);
    vm.types = ko.observableArray([]);

        ko.components.register('model-selected-component', {
            template: { element: document.getElementById('selector-component-template') },
            viewModel: SelectorComponentModel
        });
</script>
<script type="text/javascript">

    vm.selected = ko.observableArray([]);

        ko.components.register('model-selected-component', {
            template: { element: document.getElementById('selected-component-template') },
            viewModel: SelectorComponentModel
        });
</script>           

//template1
<template id="selector-component-template">
                    <div class="panelContainer">
                        <!-- ko foreach: types -->
                                <a data-bind="attr: {title: Name}, click: $parents.select" class="thumbnail text-center" href="#">
                                    <span style="display:block;height:10px;width:10px;">
                                        <i data-bind="visible: Selected" class="fa fa-check" style="color:green"></i>
                                     <img src="@Url.Content("~/Content/Images/type.png")" />
                                   </span>
                                </a>
                        <!-- /ko -->
                    </div>
</template>


//template2
<template id="selected-component-template">
    <div class="panel panel-default">
        <div class="panel-heading">Selected Properties</div>
        <div class="panel-body">
            <div class="panel-body panel-body-nobottompadding">
                <div class="panelContainer">
                    <!-- ko foreach: selected -->
                        <a class="thumbnail text-center" data-bind="attr: {title: Name}, click: $parent.select">
                            <img src="@Url.Content("~/Content/Images/type.png")" />
                        </a>
                    <!-- /ko -->
            </div>
        </div>
    </div>
</template>

//selector.js
function SelectorComponentModel(params) {

    var self = this;
    self.selected = params.selected || ko.observableArray([]);
    self.types = params.types || ko.observableArray([]);

    self.select = function (types) {
        if (self.selected.indexOf(types) == -1)
            self.selected.push(types);
        else
            self.selected.remove(types);

        types.Selected = types.Selected == true ? false : true;
        //refresh
        var data = self.types();
        self.types([]);
        self.types(data);
    }

1 个答案:

答案 0 :(得分:0)

您不应该尝试维护两个单独的阵列。只需为所有项目创建一个数组,并仅为所选项目创建computed数组。

self.items = ko.observableArray();

self.items.selected = ko.computed(() => {
    return self.items().filter(item => item.selected());
});

看看这个example

<强>更新

正如您所看到的,我使用箭头功能很多。但它们是大多数现代浏览器支持的ES6标准的一部分,您的体验可能会有所不同。对于这些不幸的用户,有more classic example

更新2

当然,您的Selected媒体资源必须可观察。在分配给模型之前,您可以为每个项目转换此属性。

Updated example