【问题标题】:knockout create an empty object from auto-mapped observable淘汰赛从自动映射的 observable 创建一个空对象
【发布时间】:2012-06-01 13:21:21
【问题描述】:

我正在尝试解决 ko 映射的一个小问题。场景是我的 ViewModel 基本上是一个对象的集合。每个对象都是通过 json 调用创建的,以这种方式:

var ViewModel = ko.observableArray();

$.getJSON(url, function(data) {
    ViewModel.push(ko.mapping.fromJSON(data));
});

这很完美,我可以在我的 HTML 中做各种魔法。 问题是,例如,如果我想在我的收藏中添加一些东西,比如说支持客户端“添加和编辑”场景。我想做类似的事情:

<input type="button" value="add new" data-bind="click: AddNew" />

我希望 ViewModel 中的 AddNew 函数类似于:

function AddNew() {
    this.push(// WHAT HERE?);
}

基本上我需要推送一个与另一个已经存在的对象相同的对象,但当然所有属性都已空白......

我正在考虑一种从列表中“克隆”一个对象并将所有可观察对象设置为空的方法,但恐怕我不知道从哪里开始:/

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

    如果您要将功能扩展到客户端编辑/添加,那么我建议您将对象形式化为 js 类,然后在内部映射这些对象。这将允许您在主视图模型上使用 add 方法并轻松创建空白实例客户端。

    映射插件的一个警告是,为了更新对象,它期望这些对象最初是由插件映射的。下面是一个简单的例子来说明如何做到这一点。

    var YourObjectClass = function (config) {
        var self = this, data;
    
        // your default structure goes here
        data = $.extend({
            name: "",
            id : -1
        }, config);
    
        ko.mapping.fromJS(data, {}, self);
    };
    
    var viewModel = function(initialData) {
        var self = this;
    
        ko.mapping.fromJS(initialData, {
            items: {
                create : function (options) {
                    return new YourObjectClass(options.data);
                }
            }
        }, self);
    
        this.AddNew = function () {
           self.items.push(new YourObjectClass());
        }
    };
    

    希望这会有所帮助。

    【讨论】:

    • “映射插件的一个警告是,对于更新对象,它期望这些对象最初是由插件映射的。这是一个如何完成的快速示例。” - 如果我早知道这一点,它会为我节省很多时间!
    【解决方案2】:

    您知道这些字段还是需要从您从服务器获得的内容中复制它们?如果是这样的话,我认为你很难开始一个新的列表。您可以创建一个模板并推送它:

    var myTemplate = {
        name: ko.observable(),
        phone: ko.observable()
    };
    
    ViewModel.push(myTemplate); // add empty item
    

    我从未见过视图模型是可观察的或可观察的数组,为什么不这样创建呢?

    function ViewModel() {
        self = this;
        self.items = ko.observableArray();
    }
    
    var myViewModel = new ViewModel();
    ko.applyBindings(myViewModel);
    
    $.getJSON(url, function(data) {
        myViewModel.items.push(ko.mapping.fromJSON(data));
    });
    

    【讨论】:

    • 第二种方式是我正在做的。我不清楚对不起,但我的意思是虚拟机只包含一个集合,我完全按照那样填充它。你是对的,我知道单个项目的属性,但我使用自动映射来避免为它们创建模板的麻烦。如果这是唯一的方法,那很好,但我想知道 ko 或映射(或单独的 JavaScript)是否提供了某种从先前存在的对象“更新”对象的方式(也许探索元数据?克隆?)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 2013-04-10
    • 2012-12-05
    • 2015-03-30
    • 1970-01-01
    • 2017-07-07
    相关资源
    最近更新 更多