Knockout.js Knockout/Select2下拉列表包含正确的选项,但现在不显示所选内容

Knockout.js Knockout/Select2下拉列表包含正确的选项,但现在不显示所选内容,knockout.js,jquery-select2,Knockout.js,Jquery Select2,所以我有两个下拉列表,我正在使用淘汰和选择。当availablePeople列表返回all false(无法正常工作)时,我可以选择并保留我选择的人。但是,当可用人员列表正常工作时,我无法看到我选择的下拉列表。要详细说明availablePeople列表,如果您选择了一个人,则该人将无法再在以后的行中被选择 HTML <div> <table id="tblPossessionChanges"> <thead> <tr>

所以我有两个下拉列表,我正在使用淘汰和选择。当availablePeople列表返回all false(无法正常工作)时,我可以选择并保留我选择的人。但是,当可用人员列表正常工作时,我无法看到我选择的下拉列表。要详细说明availablePeople列表,如果您选择了一个人,则该人将无法再在以后的行中被选择

HTML

<div>
  <table id="tblPossessionChanges">
    <thead>
      <tr>
        <th><a href="#" class="buttonSmall" data-bind="click: addPossessionChange">Add</a></th>
        <th>From</th>
        <th>To</th>
      </tr>
    </thead>
    <tbody data-bind="foreach: PossessionChanges">
      <tr>
        <td class="prompt">
          <a href="#" class="buttonSmall" data-bind="click: $root.removePossessionChange">Delete</a>           </td>
        <td>
          <select class="form-control" 
                  data-bind="options: $root.AvailableFrom, 
                             value: SelectedFrom,
                             optionsText: function(i) {return i.Name}, 
                             optionsValue: function(i) {return i.ID},
                             optionsCaption: 'Please select a Person...',
                             select2: { placeholder: 'Please select a Person...', allowClear: false}">             </select>
        </td>
        <td>
          <select class="form-control"
                  data-bind="options: $root.AvailableTo, 
                             value: SelectedTo, 
                             optionsText: function(i) {return i.Name}, 
                             optionsValue: function(i) {return i.ID},
                             optionsCaption: 'Please select a Person...',
                             select2: {placeholder: 'Please select a Person...', allowClear: false}">            </select>
        </td>
        <td>
          <span id="changeTypeSpan" data-bind="text: ChangeType"></span>
        </td>
      </tr>
    </tbody>
  </table>
</div>
这里还有JSFIDLE:
如果您将person.ID更改为person,它会工作,但选项不正确。

原始问题:
从下拉列表中选择项目时,“SelectedTo”的值将正确更改为该项目的ID值。但是,随后将重新计算下拉选项,并从选项列表中删除该项,从而使“SelectedTo”的值恢复为未定义。不能有不属于选项列表的选定值

解决方案: 这里有一个片段可以满足您的需要。我必须将根对象向下传递到我并不完全满意的OccessionChangeVM中,但它可以工作。通过这种方式,每个ObsessionChangeVM使用完整列表构建自己的可用选项列表,并且仅当项目已被使用但不是当前项目的选定项目时才进行过滤

ko.bindingHandlers.select2={
init:function(元素、valueAccessor、allBindingsAccessor、bindingContext){
ko.utils.domNodeDisposal.addDisposeCallback(元素,
函数(){
$(元素)。选择2('destroy');
});
var select2=ko.utils.unwrapObservable(allBindingsAccessor().select2);
$(元素)。选择2(选择2);
},
更新:函数(元素、valueAccessor、allBindingsAccessor、bindingContext){
var allBindings=allBindingsAccessor();
if(所有绑定中的“值”){
if((allBindings.select2.multiple | | element.multiple)&&allBindings.value().constructor!=Array){
$(element).val(allBindings.value().split(',).trigger('change');
}否则{
$(element).val(allBindings.value()).trigger('change');
}
}
$(元素)。触发器(“更改”);
}
};
函数bookOccessionTransferVM(){
var self=这个;
self.AllFromList=([{“IsAdult”:false,“Name”:“Bob”,“ID”:38438},{“IsAdult”:false,“Name”:“Gordon”,“ID”:54686},{“IsAdult”:true,“Name”:“Bill”,“ID”:45645},{“IsAdult”:false,“Name”:“Sue”,“ID”:1231},{“IsAdult”:false,“Name”:“Ling”,“ID”:123578},{“IsAdult”:false,“Name”:“Ivy”,“ID”:78945});
self.AllToList=([{“IsAdult”:false,“Name”:“Sam”,“ID”:1231},{“IsAdult”:false,“Name”:“Geoff”,“ID”:54686},{“IsAdult”:true,“Name”:“Josh”,“ID”:45645},{“IsAdult”:false,“Name”:“Sam”,“ID”:1231},{“IsAdult”:false,“Name”:“Ming”,“ID”:123578},{“IsAdult”:false,”Name“Austin”,“ID”:78945},{“IsAdult”:false,“Name”Tsz”,“ID”:true,{“IsAdult”:“Name”{:“Irelnn”,“ID”:78945},{“IsAdult”:true,“Name”:“Isabelle”,“ID”:78945},{“IsAdult”:true,“Name”:“Vickey”,“ID”:78945});
self.positionchanges=ko.observearray([]);
self.UsedTo=ko.computed(函数(){
return self.positionchanges()
.过滤器(功能(项目){
返回项目。SelectedTo()!=未定义;
})
.map(功能(项目){
返回项目。已选择返回到();
});
});
self.UsedFrom=ko.computed(函数(){
return self.positionchanges()
.过滤器(功能(项目){
返回项目。SelectedFrom()!=未定义;
})
.map(功能(项目){
返回项目。已从()中选择;
});
});
self.PossessionChanges.push(新的PossessionChangeVM(self.PossessionChanges().length+1,self));
self.GetPersonById=函数(id){
return ko.utils.arrayFirst(self.AllFromList,function(person){
返回person.ID==ko.unwrap(ID);
});
}
self.addPossessionChange=函数(){
self.PossessionChanges.push(新的PossessionChangeVM(self.PossessionChanges().length+1,self));
}
self.removePosessionChange=函数(PosessionChange){
self.positionchanges.remove(positionchange);
}
}
函数PossessionChangeVM(possessionChangeId,root){
var self=这个;
self.possessionChangeId=ko.可观察(possessionChangeId);
self.SelectedFrom=ko.observable();
self.SelectedTo=ko.observable();
self.AvailableFrom=ko.computed(函数(){
return ko.utils.arrayFilter(root.AllFromList,函数(项){
返回root.UsedFrom().indexOf(item.ID)<0 | | item.ID==self.SelectedFrom();
});
});
self.AvailableTo=ko.computed(函数(){
return ko.utils.arrayFilter(root.AllToList,函数(项){
返回root.UsedTo().indexOf(item.ID)<0 | | item.ID==self.SelectedTo();
});
});
self.ChangeType=ko.pureComputed(函数(){
if(self.SelectedFrom()!==未定义和self.SelectedTo()!==未定义){
返回“更新”;
}else if(self.SelectedFrom()==未定义和self.SelectedTo()==未定义){
返回“”;
}else if(self.SelectedFrom()==未定义){
返回“添加”;
}else if(self.SelectedTo()==未定义){
返回“删除”;
}else{返回“”;}
});
}
功能选择人员(isAdult、姓名、id){
var self=这个;
self.IsAdult=ko.可观察(IsAdult);
self.Name=ko.observable(Name);
self.ID=ko.可观察(ID);
}
ko.applyBindings(new BookOccessionTransferVM())
#TBLPossionChanges{
宽度:70%;
高度:100px;
文本对齐:居中;
表布局:固定;
}
#TBLPossionChanges td,#TBLPossionChanges th{
填充:1rem;
}
#TBLPossition更改日期{
文本对齐:居中;
}
#TBLPossition更改日期:第一个孩子{
文本对齐:左对齐;
宽度:10%
 ko.bindingHandlers.select2 = {
    init: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
      ko.utils.domNodeDisposal.addDisposeCallback(element,
        function() {
          $(element).select2('destroy');
        });
      var select2 = ko.utils.unwrapObservable(allBindingsAccessor().select2);
      $(element).select2(select2);
    },
    update: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
      var allBindings = allBindingsAccessor();
      if ("value" in allBindings) {
        if ((allBindings.select2.multiple || element.multiple) && allBindings.value().constructor != Array) {
          $(element).val(allBindings.value().split(',')).trigger('change');
        } else {
          $(element).val(allBindings.value()).trigger('change');
        }
      }
      $(element).trigger("change");
    }
    };

function BookPossessionTransferVM() {
    var self = this;

    self.AllFromList = ([{"IsAdult":false,"Name":"Bob","ID":38438}, {"IsAdult":false,"Name":"Gordon","ID":54686}, {"IsAdult":true,"Name":"Bill","ID":45645}, {"IsAdult":false,"Name":"Sue","ID":1231}, {"IsAdult":false,"Name":"Ling","ID":123578}, {"IsAdult":false,"Name":"Ivy","ID":78945}]);
    self.AllToList = ([{"IsAdult":false,"Name":"Adam","ID":38438}, {"IsAdult":false,"Name":"Geoff","ID":54686}, {"IsAdult":true,"Name":"Josh","ID":45645}, {"IsAdult":false,"Name":"Sam","ID":1231}, {"IsAdult":false,"Name":"Ming","ID":123578}, {"IsAdult":false,"Name":"Austin","ID":78945}, {"IsAdult":false,"Name":"Tsz","ID":78945}, {"IsAdult":true,"Name":"Ireylnn","ID":78945}, {"IsAdult":true,"Name":"Isabelle","ID":78945},{"IsAdult":true,"Name":"Vickey","ID":78945}]);

    self.PossessionChanges  = ko.observableArray([]);
    self.PossessionChanges.push(new PossessionChangeVM(self.PossessionChanges().length +1));

      self.GetPersonById = function (id) {
      return ko.utils.arrayFirst(self.AllFromList, function (person) {
          return person.ID === ko.unwrap(id);
        });
    }

 self.AvailableFrom = ko.computed(function() {
    var available = ko.utils.arrayFilter(self.AllFromList, function(item) {
      return !ko.utils.arrayFirst(self.PossessionChanges() , function (possessionChange) {
         var person = self.GetPersonById(possessionChange.SelectedFrom());
         if (person) {
          return person.ID === item.ID;
         } else {
           return false;
         }
      });
    });
    return available;
  });

    self.AvailableTo = ko.computed(function() {
    var available = ko.utils.arrayFilter(self.AllToList, function(item) {
      return !ko.utils.arrayFirst(self.PossessionChanges() , function (possessionChange) {
         var person = self.GetPersonById(possessionChange.SelectedTo());
         if (person) {
          return person.ID === item.ID;
         } else {
           return false;
         }
      });
    });
    return available;
  });

    self.addPossessionChange = function () {
      self.PossessionChanges.push(new PossessionChangeModel(self.PossessionChanges().length + 1));
    }

    self.removePossessionChangeChange = function(possessionChange) {
      self.PossessionChanges.remove(possessionChange);
    }
  }

  function PossessionChangeVM(possessionChangeId) {
    var self = this;

        self.possessionChangeId = ko.observable(possessionChangeId);
    self.SelectedFrom = ko.observable();
    self.SelectedTo = ko.observable();

    self.ChangeType = ko.pureComputed(function() {
      if (self.SelectedFrom() !== undefined && self.SelectedTo() !== undefined) {
        return 'Update';
      } else if (self.SelectedFrom() === undefined && self.SelectedTo() === undefined) {
          return '';
      } else if (self.SelectedFrom() === undefined) {
        return 'Add';
      } else if (self.SelectedTo() === undefined) {
        return 'Remove';
      } else { return ''; }
    });
  }

  function SelectedPerson(isAdult, name, id) {
    var self = this;

    self.IsAdult  = ko.observable(isAdult);
    self.Name = ko.observable(name);
    self.ID = ko.observable(id);
  }

  ko.applyBindings(new BookPossessionTransferVM());