【问题标题】:How to process binding : foreach after altering data in observableArray如何处理绑定:更改 observableArray 中的数据后的 foreach
【发布时间】:2020-11-02 20:56:37
【问题描述】:

我正在更改 observableArray,修改订阅事件中的一些数据。首先,我使用 ko.toJS() 转换 ObservableArray,通过数据映射并进行更改。最后我调用 self.menuCategories(jsArray) 再次设置 observableArray。

似乎我以某种方式失去了与 observableArray 的“连接”,因为我的代码中的 foreach 语句突然中断。

要么有一种更简单的方法来处理这个问题,要么我没有正确处理 observables。

代码:

var MenuWizardModel = function() {
   var self = this;
   self.menuCategories = ko.observableArray();
   self.commonDiscount = ko.observable(0);

   // Handling adding items to menuCategories.
   self.addNewSubMenuItem = function () {
        var newSubMenuItem = new SubMenuItemViewModel(self.newSubMenuItemName(), []);
        self.menuCategories.push(newSubMenuItem);
        self.newSubMenuItemName(null);
        self.createNewSubMenu(false);
    }

  function SubMenuItemViewModel(name, foodItemList) {
       var self = this;
       self.name = ko.observable(name);
       self.foodItemList = ko.observableArray(foodItemList);
  }

   self.commonDiscount.subscribe(function(val) {
        var discount = parseInt(val) / 100;
        var jsArray = ko.toJS(self.menuCategories);
        console.log(jsArray)
        jsArray = ko.toJS(jsonArray[0].foodItemList.map(item => {
            item.price = parseInt(item.price) - (parseInt(item.price) * discount);
            return item;
        }));
        self.menuCategories(jsArray);
    });

标记:

 <div data-bind="foreach: menuCategories">
          <h4 data-bind="text: name"></h4>
          <div data-bind="foreach: foodItemList" class="list-group">
          ...

数据:

【问题讨论】:

    标签: javascript arrays knockout.js


    【解决方案1】:

    我认为处理这类事情的最佳方法是向 fooditem 添加一个计算出的 observable 来捕获全局折扣并计算折扣价。

    类似于以下内容。

    var MenuWizardModel = function() {
      var self = this;
      self.menuCategories = ko.observableArray([{
        name: 'Main Meals'
      }]);
      self.commonDiscount = ko.observable(0);
      self.newSubMenuItemName = ko.observable();
      
      // Handling adding items to menuCategories.
      self.addNewSubMenuItem = function() {
        var newSubMenuItem = new SubMenuItemViewModel(self.newSubMenuItemName(), [{name: 'Oranges', price: 3.99}]);
        self.menuCategories.push(newSubMenuItem);
        self.newSubMenuItemName(null);
        //self.createNewSubMenu(false);
      }
      function mapFoodItem(item){
        item.discountedPrice= ko.pureComputed(function(){
          var discount = parseInt(self.commonDiscount()) / 100
          return parseInt(item.price) - (parseInt(item.price) * discount);
        });
        return item;
      }
      
      function SubMenuItemViewModel(name, foodItemList) {
        var self = this;
        self.name = ko.observable(name);
        self.foodItemList = ko.observableArray(foodItemList.map(mapFoodItem));
      }
    };
    
    ko.applyBindings(new MenuWizardModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <label>Discount <input data-bind="value: commonDiscount"></label>
    <label>Sub Menu Name: <input data-bind="value: newSubMenuItemName" /></label>
    <button data-bind="click: addNewSubMenuItem">Add Sub Menu</button>
    
    <div data-bind="foreach: {data: menuCategories, as: 'menu' }">
      <h4 data-bind="text: menu.name"></h4>
      <div data-bind="foreach: {data: menu.foodItemList, as: 'food'}" class="list-group">
        <div class="list-group-item">
          Name: <span data-bind="text: food.name"></span> 
          Price: <span data-bind="text: food.price"></span>
          Discounted Price: <span data-bind="text: food.discountedPrice"></span>
        </div>
      </div>
    </div>

    【讨论】:

    • 谢谢内森!...我会尽快尝试这个:)感谢您的回复!..为您提供数字啤酒:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 2016-05-26
    相关资源
    最近更新 更多