Knockout.js Knockoutjs-添加到嵌套集合而不更新UI

Knockout.js Knockoutjs-添加到嵌套集合而不更新UI,knockout.js,ko.observablearray,Knockout.js,Ko.observablearray,我有一个视图模型,它有好几层嵌套的可观察阵列 ViewModel - Dictionaries[vmDictionary] - Concepts[vmConcept] - TermGroups[vmTermGroup] - Language - Terms[vmTerm] 现在,我希望将vmTerm实例(Term对象的视图模型)添加到vmTermGroup的特定实例中,并自动更新UI

我有一个视图模型,它有好几层嵌套的可观察阵列

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;
    };
}
但是,当我将vmTerm的新实例添加到vmConcept实例时,UI不会更新以显示它。我可以console.log在调用
AddTerm
之前和之后VMTerm组中vmTerms的数量,例如,它显示2,然后显示3,但视图从未更新

我还尝试包括对
self.TermGroups()[I].Terms.valuehassmutated()
的调用,但这没有什么区别

我的怀疑是,在一个或多个级别上,我绕过了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,我担心有人会问这个问题。如果上面的编辑仍然没有帮助,那么我将尝试将其组合在一起,但它将从我正在进行的实际工作中删除,因此可能不是真实的相似性。

我对这个问题采取了不同的方法:不是使用jQuery附加事件,而是通过视图模型循环找到所需的内部视图模型,我将事件绑定添加到敲除模板中,并使用这些模板调用上下文视图模型中的函数


这可以说是我从一开始就应该做的。

乍一看,我没有发现您发布的代码中有任何问题。也许包含相关的视图代码会有所帮助?当然,我们最适合帮助您的是repro(例如JSFIDLE)。简化的小提琴会非常有用。同意Jeroen的观点,似乎没有任何问题。然后,我想再次看到vmTermGroup和vmTerm。另外,我要指出的是,循环太多了。您可以使用ko.utils.arrayFirst来选择第一个与您的条件相匹配的项目,而不必循环。一把简化的小提琴可以帮助你把它分解,并看到任何逻辑漏洞!
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);
}
<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 -->