【问题标题】:Knockoutjs - Reference local fields in computed observableKnockoutjs - 在计算的 observable 中引用本地字段
【发布时间】:2025-12-21 21:25:12
【问题描述】:

我是 KO 新手,无法让计算值正常工作。我有一个由许多对象组成的视图模型,因为我在数据库中有许多不同的表,我从中检索数据。这是我如何设置 VM 的示例。随意批评我在这里做错的任何事情(尽管它确实与计算值不同):

var viewModel = function(object1, object2...) {
    var self = this;
    var activeProductCodes = ['AB-1', 'AB-2', 'AB-3'];

    self.myFirstObject = ko.observable({
        field1: ko.observable(object1.field1),
        field2: ko.observable(object1.field2),
        field3: ko.observable(object1.field3)
    });


    self.mySecondObject = ko.observable({
        productCode: ko.observable(object2.productCode),

        isActiveProduct: ko.computed(function() {
            return self.activeProductCodes.indexOf(productCode) !== -1 ? true : false;
        }, self)
    });
}

isActiveProduct 不起作用,因为它不知道 productCode 是什么。我尝试过 this.productCode、self.productCode、self.mySecondObject().productCode,它们似乎都不起作用。 是否可以访问该值?我的整体 VM 设置是否有问题导致此操作失败?

谢谢

史蒂夫

更新: 我现在没有使对象可观察,也没有像这样声明我的虚拟机:

var viewModel = function(object1, object2...) {
    var self = this;
    var activeProductCodes = ['AB-1', 'AB-2', 'AB-3'];

    self.myFirstObject = {
        field1: ko.observable(object1.field1),
        field2: ko.observable(object1.field2),
        field3: ko.observable(object1.field3)
    }

    self.mySecondObject = {
        productCode: ko.observable(object2.productCode),

        isActiveProduct: ko.computed(function() {
            return self.activeProductCodes.indexOf(productCode) !== -1 ? true : false;
        }, self)
    }
}

【问题讨论】:

  • 为什么mySecondObject 存在?为什么不在viewModel 本身上同时拥有productCodeisActiveProduct?另一个问题 - 您是否期望 m6yFirstObjectmySecondObject 发生变化?如果不是,它们应该是 POJO 的
  • 因为产品属于第二个对象。我必须在页面上显示视图模型中的许多对象,我有一张帮助台票,他们遇到问题的产品,任何工程师访问的详细信息等等,这些都存储在数据库中的单独表中,我得单独查询。实际上有近 10 个对象。我在设置 VM 时发现,如果我没有让对象本身可观察到页面没有收到更新
  • 除非您将 whole 对象更改为另一个对象,否则它不需要是可观察的。如果您只是更改对象的 fields ,则只需使这些字段可观察。从服务器加载更新时,更新字段本身而不是整个对象
  • 是的,我没有让对象可观察,并在我的问题中添加了更新的代码,这仍然有效。当我之前尝试过此操作时,页面上的字段没有更新,但我一定是做错了其他事情。但是我仍然有我原来的问题,可计算的没有得到正确计算。如何阅读 productCode 字段?当我中断这行代码时,self 不包含 mySecondObject,这一定是我不能执行 self.productCode 的原因,那我该怎么办? PS 我稍后会按照您的回答建议更改我的子虚拟机声明
  • 恐怕你现在已经把它直接复制了。 *.com/questions/4616202/… - 我的回答给了你更好的选择。

标签: javascript knockout.js computed-observable


【解决方案1】:

除了 cmets 中的简短讨论外,当我在淘汰赛中处理子视图模型时,我倾向于正确定义它们,而不是使用匿名对象。所以在你的情况下可能看起来像这样

var viewModel = function(object1, object2...) {
    var self = this;
    var activeProductCodes = ['AB-1', 'AB-2', 'AB-3'];

    self.myFirstObject = ko.observable(new myFirstViewModel(object1)); // omitted for brevity

    self.mySecondObject = ko.observable(new mySecondViewModel(object2, activeProductCodes ));
}

var mySecondViewModel = function(object2, activeProductCodes){
    var self = this;

    self.productCode = ko.observable(object2.productCode);
    self.isActiveProduct = ko.computed(function() {
            return activeProductCodes.indexOf(self.productCode()) !== -1 ? true : false;
    }, self)
}

我还提到,您很有可能不需要子视图模型实际上是可观察的,因此您可能会侥幸成功:

self.mySecondObject = new mySeocndViewModel(object2, activeProductCodes );

这取决于您的用例。

【讨论】:

  • 谢谢,我正在更新代码,我们会反馈的!
  • mySecondViewModel里面的冒号不应该是等号吗?
  • 哇哦,它有效!非常感谢您的所有帮助和快速响应,您是救生员!我当然不会称自己为 Javascript 专家,尽管我已经使用了很多。 “自我”的概念对我来说是新的,这是我第一次使用淘汰赛,所以你帮了大忙!
  • @ministe2003 哇哦!很高兴我能帮助你。我对 KO 非常了解,并且多次遇到过这个问题,所以我知道如何解决它。