更新相关属性以响应可观察到的更改

时间:2013-07-22 17:31:24

标签: javascript knockout.js

更新

我的原帖非常长 - 这是tl; dr版本:

如何更改单个属性后更新淘汰赛模型的所有属性? update函数必须引用viewModel中的observableArray。

- 更多详情 -

我正在使用KnockoutJS。我有一个Zoo和Tapir模型以及viewmodel中的三个observable - zoos,tapirCatalog和currentTapir。 tapirCatalog从服务器填充,currentTapir保存当时正在编辑的tap的值。

这是我想要完成的事情:用户已经从他们/她的动物园的tap列表中添加了tap。在查看动物园时,用户可以编辑tap并将其替换为另一个。为此,将显示一个弹出窗口,其中包含由tap名称填充的选择表单和显示当前所选GoofinessLevel的范围。

因此,当select元素发生变化时,会更改currentTapir中的TapirId。我想要触发改变currentTapir的名字和GoofinessLevel的东西。

我尝试订阅currentTapir()。GoofinessLevel但无法触发:

function Zoo(data) {
    this.ZooId = ko.observable(data.ZooId);
    this.Tapirs = ko.observableArray(data.Tapirs);
}

function Tapir(data) {
    this.TapirId = ko.observable(data.TapirId);
    this.Name = ko.observable(data.Name);
    this.GoofinessLevel = ko.observable(data.Name);
}

function ViewModel() {
    var self = this;

    // Initializer, because I get an UncaughtType error because TapirId is undefined when attempting to subscribe to it
    var tapirInitializer = { TapirId: 0, Name: "Template", GoofinessLevel: 0 }

    self.zoos = ko.observableArray([]);
    self.tapirCatalog = ko.observableArray([]);

    self.currentTapir = ko.observable(new Tapir(tapirInitializer));

    self.currentTapir().TapirId.subscribe(function (newValue) {
        console.log("TapirId changed to: " + newValue);
    }); // This does not show in console when select element is changed
};

奇怪的是,当我订阅Tapir模型中的Goofiness级别时,我得到了触发器:

function Tapir(data) {
    var self = this;
    self.TapirId = ko.observable(data.TapirId);
    self.Name = ko.observable(data.Name);
    self.GoofinessLevel = ko.observable(data.Name);

    self.TapirId.subscribe(function (newId) {
        console.log("new TapirId from internal: " + newId);
    }); // This shows up in the console when select element is changed
}

我怀疑对于使用KO的人来说,这是一种非常常见的情况,但我无法找到任何东西。我现在已经搜索了一段时间(我可能没有正确的词汇来搜索?)。我确实找到了这个解决方案,但他从模型本身引用了viewmodel - 这似乎是反向编码,因为我认为Tap不应该对动物园有任何了解:http://jsfiddle.net/rniemeyer/QREf3/

**更新** 这是我的select元素的代码(父div有data-bind="with: currentTapir"

<select
    data-bind="attr: { id: 'tapirName', name: 'TapirId' },
        options: $root.tapirCatalog,
        optionsText: 'Name',
        optionsValue: 'TapirId',
        value: TapirId">
</select>

1 个答案:

答案 0 :(得分:1)

听起来你需要做的是将select绑定到observable而不是Id

<select
    data-bind="attr: { id: 'tapirName', name: 'TapirId' },
        options: $root.tapirCatalog,
        optionsText: 'Name',
        optionsValue: 'TapirId',
        value: currentTapir">
</select>