【问题标题】:Cannot map function in view model with json data knockout mapping无法使用 json 数据剔除映射在视图模型中映射函数
【发布时间】:2015-10-21 13:56:36
【问题描述】:

我的视图模型是这样的:

var viewModel = function(){
var self = this;
self.title = ko.observable('Hello World');
self.rows = ko.observableArray();

self.on_click = function(){
    alert('Hello World');
    var data = [
        {
            id : 1,
            x : 1,
            y : 2,
            z : 3,
        },
        {
            id : 2,
            x : 4,
            y : 5,
            z : 6,
        },
        {
            id : 3,
            x : 7,
            y : 8,
            z : 9,
        }
    ];
    self.rows(ko.unwrap(ko.mapping.fromJS(data, viewModelRow)));
    alert(self.rows());

};
};

var viewModelRow = function(){
    var self = this;
    self.id = ko.observable();
    self.x = ko.observable();
    self.y = ko.observable();
    self.z = ko.observable();
    self.mthd = function(){
        alert('Just Clicked');
    };
};
vm = new viewModel();
ko.applyBindings(vm);

我的html是这样的:

<body>
<h1 data-bind="text:title"></h1>
<div data-bind="foreach: rows">
    <table>
        <tr>
        <td data-bind="text : id"></td>
        <td data-bind="text: x"></td>
        <td data-bind="text: y"></td>
        <td data-bind="text: z"></td>
            <td><button type="button" data-bind="click: mthd">btn</button></td>
        </tr>
    </table>
</div>
<button type="button" data-bind="click: on_click">button</button>
</body>

当使用 viewModelRow 视图模型上的数据执行映射时,它会抛出错误提示

ReferenceError: mthd is not defined

我希望在 viewModelRow 中定义所有带有 viewModelRow 的 json 数据映射以及名为 mthd 的方法。 请帮忙。 JSFIDDLE 链接http://jsfiddle.net/enabqm3d/5/

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

    由于场景看起来很简单,您可以使用 .arrayMap 映射到具有 observables 的函数来实现它

    视图模型:

    var viewModelRow = function (param) {
        var self = this;
        self.id = ko.observable(param.id);
        self.x = ko.observable(param.x);
        self.y = ko.observable(param.y);
        self.z = ko.observable(param.z);
        self.mthd = function () {
            alert('im clicked')
        };
    };
    
    var viewModel = function () {
        var self = this;
        self.title = ko.observable('Hello World');
        self.rows = ko.observableArray();
        self.on_click = function () {
            var converted = ko.utils.arrayMap(data, function (item) {
                return new viewModelRow(item); // key part here
            })
            self.rows(converted); // assigning after converting everything into observables
        };
    };
    ko.applyBindings(new viewModel());
    

    忙着搞定here

    【讨论】:

    • 建议务实的方法,+1
    【解决方案2】:

    您以错误的方式使用映射插件。 fromJS 函数接受三个参数:

    fromJS(data, mappingDefinition, mappingTarget);
    

    mappingDefinition 定义了映射期间应执行的规则,例如,从数据中创建某些对象,如下所示:

    var ViewModel = function(){
        var self = this;
    
        self.title = ko.observable('Hello World');
        self.rows = ko.observableArray();
        self.init = function(){
            var data = {
                rows: [
                    {id : 1, x : 1, y : 2, z : 3,},
                    {id : 2, x : 4, y : 5, z : 6,},
                    {id : 3, x : 7, y : 8, z : 9,}
                ]
            };
    
            ko.mapping.fromJS(data, {
                rows: {
                    create: function (options) {
                        return new ViewModelRow(options.data);
                    }
                }
            }, self);
        };
    };
    
    var ViewModelRow = function(data){
        var self = this;
    
        // think whether these properties really need to be observable
        self.id = ko.observable(data.id);
        self.x = ko.observable(data.x);
        self.y = ko.observable(data.y);
        self.z = ko.observable(data.z);
        self.mthd = function(){
            alert('Just clicked ' + self.id() );
        };
    };
    
    var vm = new ViewModel();
    ko.applyBindings(vm);
     
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
    
    <h1 data-bind="text:title"></h1>
    
    <div data-bind="foreach: rows">
      <table>
        <tr>
          <td data-bind="text: id"></td>
          <td data-bind="text: x"></td>
          <td data-bind="text: y"></td>
          <td data-bind="text: z"></td>
          <td><button type="button" data-bind="click: mthd">btn</button></td>
        </tr>
      </table>
    </div>
    
    <button type="button" data-bind="click: init">init viewmodel</button>

    通读the documentation,连读的都不多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-01
      • 1970-01-01
      • 2015-01-21
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      相关资源
      最近更新 更多