首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >剔除/选择2:在图书转移应用程序中使下拉操作正确工作的问题

剔除/选择2:在图书转移应用程序中使下拉操作正确工作的问题
EN

Stack Overflow用户
提问于 2020-01-30 00:22:18
回答 1查看 56关注 0票数 0

所以我在我的申请中遇到了困难,我正试图完成。它应该发送一张清单,列出我想要的书的所有物。现在,我在淘汰赛中有几个视图模型,其中包含了通过json传入的数据。

我一直在尝试用正确的列表填充下拉列表,并跟踪发生的更改,但我没有任何运气。这是我一直试图使用的绑定,用于将列表附加到下拉列表。我可以填充它们,但是我不能选择任何东西。

代码语言:javascript
复制
 function BookPossessionTransferVM() {
    var self = this;
    self.AllFromList = ([
      {"IsAdult":false,"Name":"Bob","ID":38438}, 
      {"IsAdult":false,"Name":"Gordon","ID":54686}
    ]);
    self.PossessionChanges  = ko.observableArray([]);
    self.PossessionChanges.push(new PossessionChangeModel());
    self.AvailableFrom = ko.computed(function() {
      var possessionChangesValues = self.PossessionChanges(),
          available = ko.utils.arrayFilter(self.AllFromList, function(selectedPerson) {
            return !ko.utils.arrayFirst(possessionChangesValues , function (possessionChange) {
              if (possessionChange.SelectedFrom() !== undefined) {
                return possessionChange!= self && 
                       possessionChange.SelectedFrom().Name() === selectedPerson.Name;
              } else {
                return false;
              }});
          });
      return available;
    });
    self.AvailableTo = ko.computed(function() {
       var possessionChangesValues = self.PossessionChanges(),
          available = ko.utils.arrayFilter(self.AllToList, function(selectedPerson) {
            return !ko.utils.arrayFirst(possessionChangesValues , function (possessionChange) {
              if (possessionChange.SelectedFrom() !== undefined) {
                return possessionChange!= self && 
                       possessionChange.SelectedFrom().Name() === selectedPerson.Name;
              } else {
                return false;
              }});
          });
      return available;
    });
    self.addPossessionChange = function () {
      self.PossessionChanges.push(new PossessionChangeModel());
    }
    self.removePossessionChangeChange = function(possessionChange) {
      self.PossessionChanges.remove(possessionChange);
    }
}

function PossessionChangeModel() {
    var self = this;
    self.SelectedFrom = ko.observable(new SelectedPerson());
    self.SelectedTo = ko.observable(new SelectedPerson());
    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() {
  var self = this;

  self.IsAdult  = ko.observable(false);
  self.Name = ko.observable("None");
  self.ID = ko.observable(0);
}
 
 ko.bindingHandlers.select2 = {
    init: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
      ko.utils.domNodeDisposal.addDisposeCallback(element,
        function() {
          $(element).select2('destroy');
        });
      var select2 = ko.utils.unwrapObservable(allBindingsAccessor().options);
      $(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).on('select2:selecting', function(e) {
              var data = e.params.args.data.id;
              console.log(data);
            });
          $(element).val(allBindings.value()).trigger('change');
        }
      }
      $(element).trigger("change");
    }
};
  
ko.applyBindings(new BookPossessionTransferVM());
代码语言:javascript
复制
  #tblPossessionChanges {
    width: 70%;
    height: 100px;
    text-align: center;
    table-layout: fixed;
  }

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

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

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

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

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

  #tblReassignChanges tbody td select{
    width: 75%
  }
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/css/select2.min.css" />
<div>
  <table id="tblReassignChanges">
    <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: 'Name', 
                             optionsValue: 'ID',
                             select2: { placeholder: 'Please select a Person...', allowClear: true}">             </select>
        </td>
        <td>
          <select class="form-control"
                  data-bind="options: $root.AvailableTo, 
                             value: SelectedTo, 
                             optionsText: 'Name', 
                             optionsValue: 'ID',
                             select2: {placeholder: 'Please select a Person...', allowClear: true}">            </select>
        </td>
        <td>
          <span id="changeTypeSpan" data-bind="text: ChangeType"></span>
        </td>
      </tr>
    </tbody>
  </table>
</div>

我还尝试将optionsValue更改为使用ID,但这会覆盖我所拥有的selectedPerson对象。我愿意接受所有的建议和帮助。谢谢!

编辑:这里是复制我的问题的jsFiddle,这样可以节省空间。我也用硬编码的数据。https://jsfiddle.net/3upb0mf8/5/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-30 11:59:22

你这里有很多问题:

  1. 主要问题是假设possessionChange.SelectedFrom()包含整个person对象,而实际上它只包含它的id,因为这就是传递给optionsValue的内容。请read this answer完全理解它。您必须通过它的id.
  2. AvailableTo引用possessionChange.SelectedFrom()来检索此人,而不是possessionChange.SelectedTo().
  3. name冲突:removePossessionChangeremovePossessionChangeChange.
  4. A PossesionChange必须有一个id,以便可以删除它。

几乎没有其他问题。

我想我解决了大部分问题。还请注意,我使用的是PersonVM而不是普通对象:

代码语言:javascript
复制
function BookPossessionTransferVM() {
  var self = this;
  self.All = [new PersonVM(false,"Bob",38438), new PersonVM(false,"Gordon",54686)];
  self.PossessionChanges  = ko.observableArray([]);
  self.AvailableFrom = ko.computed(function() {
    var available = ko.utils.arrayFilter(self.All, function(item) {
      return !ko.utils.arrayFirst(self.PossessionChanges() , function (possessionChange) {
         var person = self.getPersonById(possessionChange.SelectedFrom());
         if (person) {

          return person.Name() === item.Name();
         } else {
           return false;
         }
      });
    });
    return available;
  });
  self.AvailableTo = ko.computed(function() {
    var available = ko.utils.arrayFilter(self.All, function(item) {
      return !ko.utils.arrayFirst(self.PossessionChanges() , function (possessionChange) {
        var person = self.getPersonById(possessionChange.SelectedTo());
         if (person) {
          return person.Name() === item.Name();
        } else {
          return false;
        }});
    });
    return available;
  });
  self.getPersonById = function (id) {
    return ko.utils.arrayFirst(self.All, function(person){
          return person.ID === id;
      });
  }
  self.addPossessionChange = function () {
    self.PossessionChanges.push(new PossessionChangeVM(self.PossessionChanges.length + 1));
  }
  self.removePossessionChange = function(possesion) {
    self.PossessionChanges.remove(function (item) {
      return possesion.possesionId() == item.possesionId();
    });
  }
}

function PossessionChangeVM(possesionId) {
  var self = this;
  self.possesionId = ko.observable(possesionId);
  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 PersonVM(isAdult, name, id) {
  var self = this;

  self.IsAdult  = ko.observable(isAdult);
  self.Name = ko.observable(name);
  self.ID = ko.observable(id);
}
 ko.bindingHandlers.select2 = {
  init: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
    ko.utils.domNodeDisposal.addDisposeCallback(element,
      function() {
        $(element).select2('destroy');
      });
    var select2 = ko.utils.unwrapObservable(allBindingsAccessor().options);
    $(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).on('select2:selecting', function(e) {
            var data = e.params.args.data.id;
          });
        $(element).val(allBindings.value()).trigger('change');
      }
    }
    $(element).trigger("change");
  }
};
ko.applyBindings(new BookPossessionTransferVM());
代码语言:javascript
复制
#tblPossessionChanges {
    width: 70%;
    height: 100px;
    text-align: center;
    table-layout: fixed;
  }

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

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

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

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

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

  #tblReassignChanges tbody td select{
    width: 75%
  }
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/css/select2.min.css" />
<div>
  <table id="tblReassignChanges">
    <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: 'Name', 
                             optionsValue: 'ID',
                             select2: { placeholder: 'Please select a Person...', allowClear: true}">             </select>
        </td>
        <td>
          <select class="form-control"
                  data-bind="options: $root.AvailableTo, 
                             value: SelectedTo, 
                             optionsText: 'Name', 
                             optionsValue: 'ID',
                             select2: {placeholder: 'Please select a Person...', allowClear: true}">            </select>
        </td>
        <td>
          <span id="changeTypeSpan" data-bind="text: ChangeType"></span>
        </td>
      </tr>
    </tbody>
  </table>
</div>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59977471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档