我有一个视图模型,它有几层嵌套的 observableArrays。
ViewModel
- Dictionaries[vmDictionary]
- Concepts[vmConcept]
- TermGroups[vmTermGroup]
- Language
- Terms[vmTerm]
我现在希望将 vmTerm 的实例(Term 对象的视图模型)添加到 vmTermGroup 的特定实例,并自动更新 UI。
为了实现这一点,我构建了一个返回特定 vmDictionary 对象的函数:
function vmDictionaries(dicts) {
// other JS removed for brevity
self.Dictionaries = ko.observableArray([]);
self.Get = function (id) {
for (var d = 0; d < self.Dictionaries().length; d++) {
if (self.Dictionaries()[d].ID() == id) {
return self.Dictionaries()[d];
}
}
return null;
};
}
一旦我有了特定的 vmDictionary 对象,我需要获取特定的 vmConcept 对象,它是我要添加到的 vmTermGroup 的父对象。我有这个 vmConcept 的 ID,我可以用它来检索它:
var concept;
for (var c = 0; c < dict.Concepts().length; c++) {
if (dict.Concepts()[c].ID() == conceptId) {
concept = dict.Concepts()[c];
}
}
在 vmConcept 视图模型中,我有一个函数,AddTerm
. 此函数通过检查每个 vmTermGroup 的 Language.ID 属性来确定需要哪个 vmTermGroup。
当获得匹配的 vmTermGroup 时,该函数push
将新的 vmTerm 转换为该 vmTermGroup 的术语 observableArray。
function vmConcept(concept) {
// other JS removed for brevity
self.TermGroups = ko.observableArray();
for (var i = 0; i < concept.TermGroups.length; i++) {
self.TermGroups.push(new vmTermGroup(concept.TermGroups[i]));
}
self.AddTerm = function (vmTerm) {
// loop through all the TermGroups
for (var i = 0; i < self.TermGroups().length; i++) {
// if this TermGroup.Language matches the vmTerm.Language...
if (self.TermGroups()[i].Language.ID() == vmTerm.Language.ID) {
// ...then add vmTerm to this TermGroup
self.TermGroups()[i].Terms.push(vmTerm);
return true;
}
}
return false;
}.bind(this);
}
但是,当我将 vmTerm 的新实例添加到 vmConcept 实例时,UI 不会更新以显示它。我可以在调用之前和之后 console.log 记录 vmTermGroup 中的 vmTerms 数量,AddTerm
它显示例如 2 和 3,但视图永远不会更新。
我也试过包括一个电话,self.TermGroups()[i].Terms.valueHasMutated()
但这没有什么区别。
我的怀疑是,在一个或多个级别上,我绕过了 Knockout 的可观察数组并直接潜入内部(本机)数组,这将阻止 Knockout 跟踪更改,但我看不出我还能如何实现我的目标想在这里做。
我很欣赏这是一个相当复杂的示例/问题,但是有谁知道我如何将新的 vmTerm 添加到这个内部集合中?
编辑:这是正在使用的视图模板。
<div id="concept-container" data-bind="foreach: Concepts">
<!-- markup removed for brevity -->
<div data-bind="foreach: TermGroups">
<div>
<div class="language-box" data-bind="text: Language.Title"></div>
<!-- ko foreach: Terms -->
<!-- markup removed for brevity -->
<!-- /ko -->
</div>
</div> <!-- end of foreach: TermGroups -->
</div> <!-- end of foreach: Concepts -->
这foreach: Terms
是我要添加的最里面的内容,并且没有更新。
至于 JsFiddle,我担心有人会要求这个。如果上面的编辑仍然没有帮助,那么我会尝试将一个放在一起,但它会与我实际正在进行的工作完全不同,因此可能不是真正的相似之处。