Knockout:更改可观察数组

时间:2016-11-04 19:20:28

标签: javascript jquery knockout.js

我有一个ko.observableArray()属性对象的选择绑定:

<select title="Select Property"
  data-bind="options: $root.properties,
         optionsCaption: '- Select Property -',
         optionsText: 'name',
         optionsValue: 'typeId',
         value: $root.columns()[index]
  "></select>

当有选择时,select元素显示所选的名称。这工作正常一段时间,但现在我需要在选择后修改properties observableArray。一旦我这样做,选择将恢复为optionsCaption。

this页面的底部是

部分
  

注2:对生成的选项进行后处理

我认为这可以帮助我将选择设置回显示name,但我还没弄清楚如何。

除非我可以使用JQuery来获取选择并设置名称吗?

我在想:

$("select[title='Select Property']").setAttribute();

但是选择是在一个ko foreach中生成的,所以我必须指定元素的索引才能得到它(怎么样?),即便如此,我也不确定如何让jQuery在淘汰赛中发挥出色。< / p>

我提到过我还在学习这些东西吗?

感谢。

------------------编辑------------------

显示我是如何修改数组的:

我从newValue获得oldValuesubscribeChanged,然后

if (typeof(newValue) != "undefined") {
  var newProperty = model.allProperties[newValue];
  if (model.properties.indexOf(newProperty) != -1) {
    model.properties.splice(model.properties.indexOf(newProperty), 1);
  }
  model.propertiesInUse[newValue] = index;
}

if (typeof(oldValue) != "undefined") {
  var oldProperty = model.allProperties[oldValue];

  if (model.properties.indexOf(oldProperty) == -1) {
    model.properties.unshift(oldProperty);
  }
  if (model.propertiesInUse[oldValue]) {
    delete model.propertiesInUse[oldValue];
  }
}

1 个答案:

答案 0 :(得分:0)

据我了解你的情况

- 您需要制作动态dropDown列表,以便使用尚未选择的值更新任何添加的dropDown。

- 如果删除了一个下拉列表并且有一个选定的值,则需要将该值重新添加到其他dropDowns。

以下是我的方法:

示例:https://jsfiddle.net/9aLvd3uw/251/

HTML:

<!-- ko foreach: MainPropertiesList -->
  <select title="Select Property" data-bind="value:SelectedValue">
     <option data-bind="value:'',text:'-Select Property -'"></option>
      <!-- ko foreach: Options -->
        <option data-bind="value:typeId,text:name"></option>
     <!-- /ko -->
  </select>
  <span data-bind="text:'remove',click:$root.deleteColumn"></span>
<!-- /ko -->
<hr>
<span data-bind="text:'add',click:$root.addColumn"></span>

JS:

var data = [{name:"Property1",typeId:1},{name:"Property2",typeId:2},{name:"Property3",typeId:3},{name:"Property4",typeId:4}];

ko.subscribable.fn.subscribeChanged = function (callback, context) {
    var savedValue = this.peek();
    return this.subscribe(function (latestValue) {
        var oldValue = savedValue;
        savedValue = latestValue;
        callback.call(context, latestValue, oldValue);
    });
};

var DropDownItemViewModel = function (index){
  var self = this;
  self.SelectedValue = ko.observable();
  self.Index = ko.observable(index);
  self.Options = ko.observableArray(($.map(data, function (item) {
    return new OptionItemViewModel(item);
  })));

 self.SelectedValue.subscribeChanged(function(newVal, oldValue){
    if(newVal){
     ko.utils.arrayForEach(appVM.MainPropertiesList(), function (item) {
         ko.utils.arrayForEach(item.Options(), function (item2) {
          if(item2 && item2.typeId() == newVal && self.Index() != item.Index() ){
            item.Options.remove(item2);
           if(oldValue){
              item.Options.push(new OptionItemViewModel({name:"Property" + oldValue , typeId : oldValue}));
           }
        }
      });
    });

     ko.utils.arrayForEach(appVM.SelectedPropertiesList(), function (item) {
      if(item && item.typeId() == oldValue){
         appVM.SelectedPropertiesList.remove(item);
      }
    });
    appVM.SelectedPropertiesList.push(new OptionItemViewModel({name:"Property" + newVal , typeId : newVal}));
    }
  });
}
var OptionItemViewModel = function (data){
  var self = this;
  self.name = ko.observable(data.name);
  self.typeId = ko.observable(data.typeId);
}

var AppViewModel = function(){
  var self = this;
  self.numberOfColumns = ko.observable(2);
  self.properties = ko.observableArray();
  self.MainPropertiesList = ko.observableArray();
  self.SelectedPropertiesList = ko.observableArray();
  for (var i = 0; i <= self.numberOfColumns(); i++) {
     self.MainPropertiesList.push(new DropDownItemViewModel(i));
  }
  self.deleteColumn = function(item){
    self.MainPropertiesList.remove(item);
    self.UpdateDropDowns(item);
  }
  self.addColumn = function(){
     self.MainPropertiesList.push(new DropDownItemViewModel(self.MainPropertiesList().length));
     self.UpdateAddedDropDown();
  }
  self.UpdateAddedDropDown = function(){
    var len = self.MainPropertiesList().length ; 
    ko.utils.arrayForEach(appVM.SelectedPropertiesList(), function (item) {
        ko.utils.arrayForEach(self.MainPropertiesList()[len-1].Options(), function (item2) {
        if(item && item2 && item.typeId() == item2.typeId()){
            self.MainPropertiesList()[len-1].Options.remove(item2);
        }
       });
    });
  }
  self.UpdateDropDowns = function(data){
    if(data.SelectedValue()){
     ko.utils.arrayForEach(self.MainPropertiesList(), function (item) {
         item.Options.push(new OptionItemViewModel({name:"Property" + data.SelectedValue() ,typeId:data.SelectedValue()}));
    });
    }
  }
}
var appVM = new AppViewModel();
ko.applyBindings(appVM);