knockout.js更新选择列表不会在第一次更改时触发

时间:2013-01-25 10:38:00

标签: javascript knockout.js knockout-2.0

我有2个选择列表,我想同步索引,所以当第一个索引为1时,第二个索引为1等。

这是我的HTML。

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.0/knockout-min.js"></script>

<div>
<select id="selLight" data-bind="options: $root.ddlLight, value: ddlLightSelected"></select>
<select id="selAction" data-bind="options: $root.ddlAction, value: ddlActionSelected"></select>
</div>

和javascript ...

var ViewModel = function() {
    var self = this;

    self.ddlLight  = ko.observableArray(["RED", "AMBER", "GREEN"]);
    self.ddlAction = ko.observableArray(["STOP", "READY", "GO"]);
    self.ddlLightSelected  = ko.observable();
    self.ddlActionSelected = ko.observable();

    self.ddlLightSelected.subscribe(function (event) {
        document.getElementById("selAction").selectedIndex =
            self.ddlLight.indexOf(self.ddlLightSelected());
     });

    self.ddlActionSelected.subscribe(function (event) {
        document.getElementById("selLight").selectedIndex =
            self.ddlAction.indexOf(self.ddlActionSelected());
     });    
};

ko.applyBindings(new ViewModel()); 

我有一个确切问题的小提琴......

http://jsfiddle.net/phykell/2vUTw/

编辑:我和jsfiddle有一些问题,所以这里有一个jsbin ... http://jsbin.com/ilomer/4/

...以下是重建问题的方法:

  1. 运行jsFiddle
  2. 从灯光中选择绿色(操作将更改为GO)3。从操作中选择停止(灯光应更改为红色但不会更改)

1 个答案:

答案 0 :(得分:4)

问题在于这行代码:

document.getElementById("selAction").selectedIndex = self.ddlLight.indexOf(self.ddlLightSelected());

您正在直接更改DOM,不允许Knockout启动可观察模式。

如果您想要更改内容,请始终更改ko.observable,而不是JavaScript变量或DOM。 Knockout将识别这一变化,并因此改变DOM本身。解决方案是:

self.ddlLightSelected.subscribe(function (event) {
      var index = self.ddlLight.indexOf(self.ddlLightSelected());
      self.ddlActionSelected(self.ddlAction()[index]); // Update the Observable, not the DOM
});

self.ddlActionSelected.subscribe(function (event) {
    var index = self.ddlAction.indexOf(self.ddlActionSelected());
    self.ddlLightSelected(self.ddlLight()[index]); // Update the Observable, not the DOM
}); 

Updated JS Bin