【问题标题】:How do I append to a mapped observable array in Knockout.js?如何在 Knockout.js 中附加到映射的可观察数组?
【发布时间】:2016-01-18 14:51:01
【问题描述】:

如何在 Knockout.js 中向可编辑表中添加一行?

var data = {
    "Lines": [
        {"Entries": [{"Hours": 5.5},{"Hours": 2.50},{"Hours": 3.75}]}, 
        {"Entries": [{"Hours": 5.1},{"Hours": 2.00},{"Hours": 4.75}]},
        {"Entries": [{"Hours": 1.2},{"Hours": 3.00},{"Hours": 2.12}]}
    ]
}
var data1 = {"Entries": [{"Hours": 0},{"Hours": 0},{"Hours": 0}],Total:0};

表格显示 self.List(),这是一个 observableArray 映射到 data.Linesself.List(ko.mapping.fromJS(data.Lines)())

[{"Entries":[{"Hours":"33.5"},{"Hours":2.5},{"Hours":3.75}],"Total":39.75},{"Entries":[{"Hours":5.1},{"Hours":2},{"Hours":4.75}],"Total":11.85},{"Entries":[{"Hours":1.2},{"Hours":3},{"Hours":2.12}],"Total":6.32}]

当我单击 addRow 按钮时,我想我需要重新计算 self.List()。我从why-can-not-i-concat-data-to-observable-array-in-knockout尝试过

self.addRow =function(){
    self.List(self.List().concat(data1))
    self.applyTotals();
}

如果我不添加一行,applyTotoals 可以正常工作。

self.applyTotals = function(){
    ko.utils.arrayForEach(self.List(), function(vm){
        vm.Total = ko.computed(function(){
            var s = 0;
            ko.utils.arrayForEach(this.Entries(), function(entry){
                var p = parseFloat(entry.Hours(), 10);
                if (!isNaN(p)) {
                    s += p;
                }
            });
            return s;
        }, vm);
    });
}    

但我得到uncaught TypeError:this.Entries is not a function 并且新行不会计算总数。所以我试过了

self.addRow =function(){
    self.List = ko.computed(function(){
        var orig = self.List();
        var os= ko.toJS(orig);
        os.push(data1)
        console.log(JSON.stringify(os))
        var oa = ko.observableArray([]);
        return oa(ko.mapping.fromJS(os)());            
    })
}

如何修改映射的 observableArray?

这里是小提琴:http://jsfiddle.net/mckennatim/jngesuf2/

【问题讨论】:

    标签: javascript knockout.js knockout-mapping-plugin


    【解决方案1】:

    @mcktimo 你没有有效地使用mapping 插件。您可以在 fromJS 函数中使用2nd paramter Mapper 并有效地构建您的viewModel。

    视图模型:

     function model(data) {
         var self = this;
         self.Entries = ko.observableArray();
         self.Total = ko.computed(function () {
             var sum = 0;
             ko.utils.arrayForEach(self.Entries(), function (entry) {
                 var value = parseFloat(entry.Hours(), 10);
                 if (!isNaN(value)) {
                     sum += value;
                 }
             });
             return sum;
         });
         ko.mapping.fromJS(data, {}, self);
     }
    
     var mapping = { //everything goes through this point
         create: function (options) {
             return new model(options.data);
         }
     }
    
     function ViewModel() {
         var self = this
         self.List = ko.observableArray([])
         self.LoadData = function (data) {
             ko.mapping.fromJS(data.Lines, mapping, self.List)
         }
         self.LoadData(data);
         self.addRow = function () {
             self.List.push(ko.mapping.fromJS(data1, mapping));
         }
     }
     ko.applyBindings(new ViewModel(), document.getElementById('ko')) 
    

    工作示例here

    我建议深入了解映射documentation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 2018-11-26
      • 1970-01-01
      相关资源
      最近更新 更多