如何使用foreach绑定在多个select中设置默认选择

时间:2017-08-22 09:47:59

标签: knockout.js

您好我正在尝试在for循环中默认选择多个绑定 我有以下情况。 公司有productList和managerList 每个经理都有自己的prefered_products与公司的产品清单。 我想在表格中显示这些数据。我想制作经理和公司其他产品的首选产品 html文件

 <tbody data-bind="foreach: Managers">
  <tr >       
    <td class="col-xs-2">
         <select type="text" data-bind="options:$parent.productList,optionsText:'name', selectedOptions:prefered_products'" class="form-control" ></select>
     </td> 
 </tr>

js file

var products = [ {name: 'product1', _id : 'abc'},{name: 'product2', _id : 'def'},{name: 'product3', _id : 'ghi'}]
var managers = [ {_id : 'mand', name: 'kate', prefered_products: [{name: 'product2', _id : 'def'},{name: 'product3', _id : 'ghi'}] },
                 {_id : 'todhm', name: 'jordan', prefered_products :[{name: 'product1', _id : 'abc'},{name: 'product2', _id : 'def'}]}]
var ManagerData =function(data){
    var self = this
    self.id = ko.observable(data._id);
    self.name = ko.observable(data.name);
    self.prefered_products = ko.observableArray([]);
    self.add_product = function(product){
            self.prefered_products.push(new Product(product));
    }
    for(i=0; i< data.prefered_products.length;i++){
        self.add_product(data.prefered_products[i]);
    }
}
var ProductType = function(data){
    var self = this;
    self.name = ko.observable(data.name);
    self._id = ko.observable(data._id);
}
var ViewModel = function(){
   self.productList = ko.observableArray([]);
   self.managerList = ko.observableArray([]);
}
var ViewModel = new ViewModel();
ko.applyBindings(ViewModel);
products.forEach(function(product,index){
                       ViewModel.productList.push(new Product(product));
                   });
managers.forEach(function(manager,indexdo){
                      ViewModel.ManagerList.push(new ManagerData(manager));
                                 });

1 个答案:

答案 0 :(得分:0)

您的代码段包含许多错误,因此我带走了那些没有运行的部分。

您应该知道的最重要的事情是,product数据中的manager个对象不同的引用而不是products数组中的对象。

您需要使用product1._id === product2._id使用product1 === product2而不是来比较它们。

例如:

&#13;
&#13;
var products = [ {name: 'product1', _id : 'abc'},{name: 'product2', _id : 'def'},{name: 'product3', _id : 'ghi'}]
var managers = [ {_id : 'mand', name: 'kate', prefered_products: [{name: 'product2', _id : 'def'},{name: 'product3', _id : 'ghi'}] },
                 {_id : 'todhm', name: 'jordan', prefered_products :[{name: 'product1', _id : 'abc'},{name: 'product2', _id : 'def'}]}]

var Manager = function(data) {
  this.name = data.name;
  
  this.preferedIds = {};
  
  data.prefered_products.forEach(
    function(prod) { this.preferedIds[prod._id] = true; },
    this
  )
};

Manager.from = function(data) { return new Manager(data); };

var App = function() {
  this.managers = managers.map(Manager.from);
  this.products = products;

  // For one manager
  this.selectedManager = ko.observable(null);
  
  // For multiple managers
  this.selectedManagers = ko.observable([]);
  
  this.selectedProducts = ko.observableArray([]);
  
  this.selectedManager.subscribe(function(manager) {
  
    // Set the selectedProducts to the ones whose ids are
    // in the manager's prefered ids
    this.selectedProducts(
      App.productsInIdSet(products, manager.preferedIds)
    );
  }, this);
  
  this.selectedManagers.subscribe(function(selectedManagers) {
    var allIds = selectedManagers.reduce(function(all, manager) {
      return Object.assign(all, manager.preferedIds);
    }, {});
    
    this.selectedProducts(
      App.productsInIdSet(products, allIds)
    );
    
  }, this);

};

App.productsInIdSet = function(products, idSet) {
  return products.filter(function(product) {
    return idSet[product._id];
  });
}



ko.applyBindings(new App());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<h2>For one manager</h2>

<select data-bind="options: managers, 
                   optionsText: 'name', 
                   value: selectedManager"></select>
                   
<select data-bind="options: products,
                   optionsText: 'name',
                   selectedOptions: selectedProducts" multiple></select>
                   
<h2>For multiple managers</h2>
<em>Note that from a user-experience point of view, it's very annoying that this clears any custom selections when the manager selection changes.</em>

<select data-bind="options: managers, 
                   optionsText: 'name', 
                   selectedOptions: selectedManagers" multiple></select>
                   
<select data-bind="options: products,
                   optionsText: 'name',
                   selectedOptions: selectedProducts" multiple></select>
&#13;
&#13;
&#13;