我有一个视图模型,它有几层嵌套的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);
}
但是,当我向vmConcept实例添加新的vmTerm实例时,UI不会更新以显示它。我可以在调用AddTerm
之前和之后调用vmTermGroup中的vmTerms数量,并显示例如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,我担心有人会要求这样做。如果上面的编辑仍然没有帮助,那么我会尝试将它们放在一起,但它会从我的实际工作中完全删除,因此可能不是真正的相似。
答案 0 :(得分:1)
我采用了不同的方法来解决这个问题:我没有使用jQuery来附加事件,而是通过视图模型循环来查找所需的内部视图模型,我将事件绑定添加到我的Knockout模板并使用它们来调用上下文视图模型中的函数。
这可以说是我从一开始就应该做的事情。