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

因此,我有两个下拉列表供我使用,并用于剔除和选择。当availablePeople列表返回所有false(不能正常工作)时,我可以选择并保留我选择的人。但是,当可用人员列表正常工作时,我看不到我选择的下拉菜单。要详细说明可用的人员列表,如果您选择一个人,则该人将不再可以在以后的行中选择。

的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>

JS

 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());

这也是jsfiddle:https ://jsfiddle.net/cpd5w9he/11/如果将person.ID更改为person,它可以工作,但是选项不正确

杰森·斯帕克(Jason Spake)

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

解决方案:以下代码片段可以满足您的需求。我不得不将根对象传递给PossessionChangeVM,我并不完全满意,但是它可以工作。这样,每个ownerChangeVM都使用FullList构建其自己的可用选项列表,并且仅在使用了该项目但不是当前项目的选定项目时进行过滤。

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.UsedTo = ko.computed(function(){
    	return self.PossessionChanges()
        .filter(function(item){
          return item.SelectedTo() != undefined;
        })
        .map(function(item){
          return item.SelectedTo();
        });
    });
    self.UsedFrom = ko.computed(function(){
    	return self.PossessionChanges()
        .filter(function(item){
          return item.SelectedFrom() != undefined;
        })
        .map(function(item){
          return item.SelectedFrom();
        });
    });

    self.PossessionChanges.push(new PossessionChangeVM(self.PossessionChanges().length +1, self));
    
      self.GetPersonById = function (id) {
      return ko.utils.arrayFirst(self.AllFromList, function (person) {
          return person.ID === ko.unwrap(id);
        });
    }

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

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

  function PossessionChangeVM(possessionChangeId, root) {
    var self = this;

		self.possessionChangeId = ko.observable(possessionChangeId);
    self.SelectedFrom = ko.observable();
    self.SelectedTo = ko.observable();
  
    
    self.AvailableFrom = ko.computed(function() {
      return ko.utils.arrayFilter(root.AllFromList, function(item) {
        return root.UsedFrom().indexOf(item.ID) < 0 || item.ID === self.SelectedFrom();
      });
  	});
    
    self.AvailableTo = ko.computed(function() {
      return ko.utils.arrayFilter(root.AllToList, function(item) {
        return root.UsedTo().indexOf(item.ID) < 0 || item.ID === self.SelectedTo();
      });
  	});

    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());
#tblPossessionChanges {
    width: 70%;
    height: 100px;
    text-align: center;
    table-layout: fixed;
  }

  #tblPossessionChanges td, #tblPossessionChanges th {
    padding: 1rem;
  }

  #tblPossessionChanges thead th {
    text-align: center;
  }

  #tblPossessionChanges thead th:first-child {
    text-align: left;
    width: 10%;
  }

  #tblPossessionChanges tbody td:first-child {
    text-align: left;
    width: 10%;
  }

  #tblPossessionChanges > tbody > tr > td.prompt > a{
    font-weight: bold;
  }

  #tblPossessionChanges tbody td select{
    width: 75%
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />

<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: 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: 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>
  <br/>

</div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

tinymce-knockout-binding不显示格式

来自分类Dev

Knockout ValidationMessage 绑定不显示消息

来自分类Dev

Knockout.js arrayFilter多个下拉列表

来自分类Dev

Knockout.js多个下拉列表。

来自分类Dev

使用Knockout显示JSON响应的内容

来自分类Dev

使用Knockout显示JSON响应的内容

来自分类Dev

Knockout.js foreach不显示的项目列表

来自分类Dev

Select2 selected tag as object instead of 'id' in Knockout

来自分类Dev

Knockout.js与多个Select2绑定

来自分类Dev

使用Struts标记在UI中无法正确显示Select2下拉列表

来自分类Dev

使用jQuery更新Knockout.js下拉列表和Knockout值

来自分类Dev

选择元素未使用 Knockout 正确更新

来自分类Dev

使用foreach Knockout绑定更新列表项

来自分类Dev

Knockout.js和大型数据集也使下拉列表变慢

来自分类Dev

从Knockout.js的下拉列表中获取选定的值

来自分类Dev

Knockout JS中带有下拉列表的数组

来自分类Dev

jQuery mobile 1.4 select的Knockout.js 3.3.0选项绑定

来自分类Dev

jQuery mobile 1.4 select的Knockout.js 3.3.0选项绑定

来自分类Dev

从select2下拉列表中选择某个选项后触发动作

来自分类Dev

如何使用从Select2下拉列表中选择的选项来触发jQuery?

来自分类Dev

使用Ajax时清除select2下拉列表的正确方法是什么?

来自分类Dev

Knockout.js hasfocus实现在动态添加的行上

来自分类Dev

以为我了解 Knockout.js,现在我不太确定

来自分类Dev

Select2具有Knockout.js初始值

来自分类Dev

Select2选择标签作为对象,而不是Knockout中的'id'

来自分类Dev

嵌套值上的Knockout.js映射选项被忽略

来自分类Dev

Knockout.js:合并javascript对象并选择选项

来自分类Dev

动态更改选项文本-knockout.js

来自分类Dev

使用Knockout填充列表时,使用AngularJs过滤列表

Related 相关文章

  1. 1

    tinymce-knockout-binding不显示格式

  2. 2

    Knockout ValidationMessage 绑定不显示消息

  3. 3

    Knockout.js arrayFilter多个下拉列表

  4. 4

    Knockout.js多个下拉列表。

  5. 5

    使用Knockout显示JSON响应的内容

  6. 6

    使用Knockout显示JSON响应的内容

  7. 7

    Knockout.js foreach不显示的项目列表

  8. 8

    Select2 selected tag as object instead of 'id' in Knockout

  9. 9

    Knockout.js与多个Select2绑定

  10. 10

    使用Struts标记在UI中无法正确显示Select2下拉列表

  11. 11

    使用jQuery更新Knockout.js下拉列表和Knockout值

  12. 12

    选择元素未使用 Knockout 正确更新

  13. 13

    使用foreach Knockout绑定更新列表项

  14. 14

    Knockout.js和大型数据集也使下拉列表变慢

  15. 15

    从Knockout.js的下拉列表中获取选定的值

  16. 16

    Knockout JS中带有下拉列表的数组

  17. 17

    jQuery mobile 1.4 select的Knockout.js 3.3.0选项绑定

  18. 18

    jQuery mobile 1.4 select的Knockout.js 3.3.0选项绑定

  19. 19

    从select2下拉列表中选择某个选项后触发动作

  20. 20

    如何使用从Select2下拉列表中选择的选项来触发jQuery?

  21. 21

    使用Ajax时清除select2下拉列表的正确方法是什么?

  22. 22

    Knockout.js hasfocus实现在动态添加的行上

  23. 23

    以为我了解 Knockout.js,现在我不太确定

  24. 24

    Select2具有Knockout.js初始值

  25. 25

    Select2选择标签作为对象,而不是Knockout中的'id'

  26. 26

    嵌套值上的Knockout.js映射选项被忽略

  27. 27

    Knockout.js:合并javascript对象并选择选项

  28. 28

    动态更改选项文本-knockout.js

  29. 29

    使用Knockout填充列表时,使用AngularJs过滤列表

热门标签

归档