骨干.js 模型指向嵌套模型的同一实例 [英] backbone.js models pointing to same instance of nested model

查看:19
本文介绍了骨干.js 模型指向嵌套模型的同一实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用backbone.js,这是一个快速测试来演示我在使用嵌套模型时遇到的问题.

Using backbone.js, here is a quick test to demonstrate the problem I am facing with nested models.

前言我有一个包含 2 个嵌套模型 Obj1 和 Obj2 的 Obj 模型.Obj模型本身有一个View(ObjView),主页面本身也有一个View(BodyView).

Preface I have a Obj Model that contains 2 nested models, Obj1 and Obj2. The Obj model itself has a View (ObjView), and there is a View for the main page itself (BodyView).

主页有一个按钮,id=add.每次点击按钮时,都会在ObjCollection中添加一个新的Obj,ObjView在页面中添加一个按钮(id=clickMe).clickMe 按钮绑定到一个 testFunc,该 testFunc 控制台记录 this.model 和 this.model.get("obj1").

The main page has a single button, id=add. Each time the button is clicked, a new Obj is added to the ObjCollection, and the ObjView adds a button (id=clickMe) to the page. The clickMe button is bound to a testFunc that console.logs this.model and this.model.get("obj1").

问题通过检查 console.logs,我看到虽然每个 Obj 都是一个新实例,但它们嵌套的 Obj1 指向 obj1 的同一个实例!但是每个 Obj 实例显然都应该有它们自己的嵌套模型 obj1 和 obj2 的实例.

Problem From inspecting the console.logs, I see that while each Obj is a new instance, their nested Obj1 point to the same instance of an obj1! But each instance of Obj is obviously supposed to have their own instances of the nested models obj1 and obj2.

感谢任何帮助.

$(document).ready(function(){

    var Obj1 = Backbone.Model.extend({
        defaults:{
            Attr1A   : false,
            Attr1B   : false
        }
    })

    var Obj2 = Backbone.Model.extend({
        defaults:{
            Attr2A   : false,
            Attr2B   : false
        }
    })

    var Obj = Backbone.Model.extend({
        defaults: {
            obj1    : new Obj1(),
            obj2    : new Obj2()
        }
    })

    var ObjCollection = Backbone.Collection.extend({
        model: Obj
    });


    var ObjView = Backbone.View.extend({

        initialize: function(){
            _.bindAll(this, 'render', 'testFunc');
            this.model.bind('change', this.render);
            this.model.view = this;

            $("body").append(this.render().el);
        },

        events: {
            "click #clickMe" : "testFunc"
        },

        render: function(){
            $(this.el).html('<input type ="button" id="clickMe" value="Click">')
            return this;
        },

        testFunc: function(){
            console.log(this.model); //returns Obj models with unique cids
            console.log(this.model.get("obj1")); //returns Obj1 models with the SAME cid!
        }
    });


    var BodyView = Backbone.View.extend({
        el: $('body'),

        events:{
            "click #add"  : "addObj"
        },

        initialize: function(){
            _.bindAll(this, 'render', 'addObj')
            this.collection = new ObjCollection();
            this.collection.bind('add', this.appendObj); 
        },

        addObj: function(){
            var myObj = new Obj();
            this.collection.add(myObj);
        },

        appendObj: function(myObj){
            var objView = new ObjView({
                model: myObj
            });
        }
    });
    var bodyView = new BodyView;

});

html 页面如下,加载了 jQuery 和主干.

The html page is just the following with jQuery and backbone loaded.

<body>
    <input type ="button" id="add" value="Add">
</body>

推荐答案

fortuneRice,当 Backbone 模型被初始化时,super.constructor 将默认值移动到内部属性数组,其中 model.get 查找obj1".Prusse 的示例使用每个实例的新对象初始化 obj1 和 obj2 值,但不会将值移动到内部属性数组.这是我对 Prusse 解决方案的修改.

fortuneRice, when a Backbone model gets initialized, the super.constructor moves the defaults to the internal attributes array, where model.get looks for "obj1". Prusse's example initializes the obj1 and obj2 values with new objects for each instance, but doesn't move the values to the internal attributes array. Here is my modification of Prusse's solution.

var Obj = Backbone.Model.extend({
    initialize: function() {
        myDefaults = {
            obj1: new Obj1();
            obj2: new Obj2();
        }
        this.set(myDefaults);
});

jQuery 的扩展方法将组合这两个对象.您可以在 initialize 方法中使用默认值声明非对象引用,并使用 myDefaults 声明对象引用.

jQuery's extend method would combine the two objects. You could declare the non-object references with defaults and the object references with myDefaults in the initialize method.

这篇关于骨干.js 模型指向嵌套模型的同一实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆