敲除和选择器的数组过滤问题

时间:2014-10-30 20:53:43

标签: javascript knockout.js

我有一系列文字,我在<select>显示。

文本可能有不同的版本号,我想根据最新版本过滤<select>

我想有更优雅的方法(建议欢迎),但我选择使用2 <select> s设置来替代可见性,具体取决于复选框。

代码是一个黑客,但结果看起来很不错。不幸的是有一个错误。

我有两个observable,指示各自数组中的选定选项:

self.SelectedText = ko.observable();
self.SelectedUnique = ko.observable();

两者都有订阅,但是我不能在两个订阅中将它们链接在一起,所以我选择了一个作为另一个的对象:

self.SelectedUnique.subscribe(function (text) {
    if (text) {
        self.SelectedText(text);
    }
});

然而,失去同步。

场景1:选择文本1,2,3。 [好] 场景2:选择文本2;选中“仅限最新版本”

这不会显示任何选项(“选择...”)。不是我想要的。

情况变得更糟。

场景3:取消选中;选择文字3;然后再次选中“仅限最新版本”。

现在,所选的选项设置为选择未过滤的选项#2。

可能有一个简单的问题。我可能无法让它发挥作用。这是小提琴:小提琴:http://jsfiddle.net/h5mt51gv/6/

所有帮助和建议表示赞赏!

1 个答案:

答案 0 :(得分:1)

我简化了你的方法:

  • <select>绑定到计算的选项列表(visibleTextBatches
  • 此计算列表取决于复选框(latestOnly)的状态,有效地在完整列表和已过滤列表之间切换
  • 已过滤的列表(latestTextBatches)是另一个计算出的,用于保存每个组的最新版本
  • <select>将实际选定的TextBatch对象存储在可观察的(selectedTextBatch
  • 订阅visibleTextBatches会导致最新的可选TextBatch在过滤列表时成为当前的function TextBatch(data) { this.textbatchId = data.textbatchId; this.parentId = data.parentId; this.version = data.version; this.title = ko.observable(data.title); } function ViewModel() { var self = this; // read up on the mapping plugin, too self.textBatches = ko.observableArray([ new TextBatch({textbatchId: 1, parentId: 1, version: 1, title: "TB1.1"}), new TextBatch({textbatchId: 2, parentId: 1, version: 2, title: "TB1.2"}), new TextBatch({textbatchId: 3, parentId: 3, version: 1, title: "TB2.1"}) ]); self.selectedTextBatch = ko.observable(); self.latestOnly = ko.observable(false); self.latestTextBatchGroups = ko.computed(function () { var latest = {}; ko.utils.arrayForEach(self.textBatches(), function (batch) { if (!latest.hasOwnProperty(batch.parentId) || batch.version > latest[batch.parentId].version ) latest[batch.parentId] = batch; }); return latest; }); self.latestTextBatches = ko.computed(function () { return ko.utils.arrayFilter(self.textBatches(), function (batch) { return batch === self.latestTextBatchGroups()[batch.parentId]; }); }); self.visibleTextBatches = ko.computed(function () { return self.latestOnly() ? self.latestTextBatches() : self.textBatches(); }); self.visibleTextBatches.subscribe(function () { var selectedBatch = self.selectedTextBatch(); if (selectedBatch && self.latestOnly()) { self.selectedTextBatch( self.latestTextBatchGroups()[selectedBatch.parentId] ); } }); } ko.applyBindings(new ViewModel());。当列表未经过滤时,它什么都不做。

&#13;
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div>
    <select data-bind="
        options: visibleTextBatches, 
        optionsText: 'title',
        optionsCaption: 'Select...',
        value: selectedTextBatch
    " />
</div>

<div>
    <input type="checkbox" id="chkLatestOnly" data-bind="checked: latestOnly" />
    <label for="chkLatestOnly">Latest only</label>
</div>

<hr />
<pre data-bind="text: ko.toJSON($root, null,2)"></pre> 
&#13;
{{1}}
&#13;
&#13;
&#13;