Нокаут: установить заголовок select после изменения наблюдаемого массива

I have a select bound to a ko.observableArray()of property objects:

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

При выделении элемент select отображает выбранное имя. Некоторое время это работало нормально, но теперь мне нужно изменить propertiesobservableArray после выбора. Как только я это сделаю, select вернется к optionsCaption.

В нижней части этой страницы находится раздел

Примечание 2: постобработка сгенерированных параметров

Я думаю, что это может помочь мне установить select обратно на отображениеname, но я не понял, как.

За исключением того, что я могу использовать JQuery, чтобы захватить select и установить имя?

Я думаю что-то вроде:

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

но select генерируется в ko foreach, поэтому я должен был бы указать индекс элемента, чтобы получить его (как?) и даже тогда я не уверен, как заставить JQuery хорошо играть с нокаутом.

Я упоминал, что все еще изучаю большинство этих вещей?

Спасибо.

—————— РЕДАКТИРОВАТЬ ——————

Чтобы показать, как я изменяю массив:

Я получаю newValueи oldValueотsubscribeChanged, тогда

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 ответ

  1. Насколько я понимаю ваш случай

    — Вы должны сделать динамический выпадающий список таким образом, чтобы любой добавленный раскрывающийся список обновлялся со значениями, которые еще не были выбраны.

    -Если выпадающий список удаляется и имеет выбранное значение, то это значение должно быть добавлено в другие выпадающие списки.

    Ниже приведен мой подход :

    Пример : 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);