Backbone.js获取并设置嵌套对象属性

如何解决Backbone.js获取并设置嵌套对象属性

| 我对Backbone.js的get和set函数一个简单的问题。 1)使用下面的代码,如何直接\'get \'或\'set \'obj1.myAttribute1? 另一个问题: 2)在模型中,除了认对象之外,我还能/应该在何处声明模型的其他属性,以便可以通过Backbone的get和set方法对其进行访问?
var MyModel = Backbone.Model.extend({
    defaults: {
        obj1 : {
            \"myAttribute1\" : false,\"myAttribute2\" : true,}
    }
})

var MyView = Backbone.View.extend({
    myFunc: function(){
        console.log(this.model.get(\"obj1\"));
        //returns the obj1 object
        //but how do I get obj1.myAttribute1 directly so that it returns false?
    }
});
我知道我可以做:
this.model.get(\"obj1\").myAttribute1;
但这是好习惯吗?     

解决方法

        虽然
this.model.get(\"obj1\").myAttribute1
很好,但这还是有问题的,因为那样的话您可能会想为set做相同类型的事情,即
this.model.get(\"obj1\").myAttribute1 = true;
但是,如果这样做,您将无法获得
myAttribute1
的Backbone模型的好处,例如更改事件或验证。 更好的解决方案是永远不要在模型中嵌套POJSO(“纯旧JavaScript对象”),而嵌套自定义模型类。所以看起来像这样:
var Obj = Backbone.Model.extend({
    defaults: {
        myAttribute1: false,myAttribute2: true
    }
});

var MyModel = Backbone.Model.extend({
    initialize: function () {
        this.set(\"obj1\",new Obj());
    }
});
然后访问代码将是
var x = this.model.get(\"obj1\").get(\"myAttribute1\");
但更重要的是,设置代码为
this.model.get(\"obj1\").set({ myAttribute1: true });
这将触发适当的更改事件等。此处的工作示例:http://jsfiddle.net/g3U7j/     ,        我为此创建了骨架深层模型-只需扩展Backbone.DeepModel而不是Backbone.Model,然后即可使用路径获取/设置嵌套模型属性。它也维护变更事件。
model.bind(\'change:user.name.first\',function(){...});
model.set({\'user.name.first\': \'Eric\'});
model.get(\'user.name.first\'); //Eric
    ,        Domenic的解决方案可以使用,但是每个新的MyModel都指向相同的Obj实例。 为了避免这种情况,MyModel应该如下所示:
var MyModel = Backbone.Model.extend({
  initialize: function() {
     myDefaults = {
       obj1: new Obj()
     } 
     this.set(myDefaults);
  }
});
有关完整说明,请参见c3rin的答案@ https://stackoverflow.com/a/6364480/1072653。     ,        我使用这种方法。 如果您有这样的骨干网模型:
var nestedAttrModel = new Backbone.Model({
    a: {b: 1,c: 2}
});
您可以使用以下方法设置属性“ a.b”:
var _a = _.omit(nestedAttrModel.get(\'a\')); // from underscore.js
_a.b = 3;
nestedAttrModel.set(\'a\',_a);
现在,您的模型将具有以下属性:
{a: {b: 3,c: 2}}
触发了“更改”事件。     ,        目前尚无人想到的一种解决方案可供使用。确实,您不能直接设置嵌套属性,除非您使用了可能不想要的第三方库。但是,您可以做的是克隆原始字典,在其中设置嵌套属性,然后设置整个字典。小菜一碟。
//How model.obj1 looks like
obj1: {
    myAttribute1: false,myAttribute2: true,anotherNestedDict: {
        myAttribute3: false
    }
}

//Make a clone of it
var cloneOfObject1 = JSON.parse(JSON.stringify(this.model.get(\'obj1\')));

//Let\'s day we want to change myAttribute1 to false and myAttribute3 to true
cloneOfObject1.myAttribute2 = false;
cloneOfObject1.anotherNestedDict.myAttribute3 = true;

//And now we set the whole dictionary
this.model.set(\'obj1\',cloneOfObject1);

//Job done,happy birthday
    ,        @Domenic \的解决方案对@pagewil和@Benno也有相同的问题。我的答案是改写一个简单的Backbone.Model子类来解决问题。
// Special model implementation that allows you to easily nest Backbone models as properties.
Backbone.NestedModel = Backbone.Model.extend({
    // Define Backbone models that are present in properties
    // Expected Format:
    // [{key: \'courses\',model: Course}]
    models: [],set: function(key,value,options) {
        var attrs,attr,val;

        if (_.isObject(key) || key == null) {
            attrs = key;
            options = value;
        } else {
            attrs = {};
            attrs[key] = value;
        }

        _.each(this.models,function(item){
            if (_.isObject(attrs[item.key])) {
                attrs[item.key] = new item.model(attrs[item.key]);
            }
        },this);

        return Backbone.Model.prototype.set.call(this,attrs,options);
    }
});

var Obj = Backbone.Model.extend({
    defaults: {
        myAttribute1: false,myAttribute2: true
    }
});

var MyModel = Backbone.NestedModel.extend({
    defaults: {
        obj1: new Obj()
    },models: [{key: \'obj1\',model: Obj}]
});
NestedModel为您所做的就是允许这些工作(当通过JSON数据设置myModel时会发生这种情况):
var myModel = new MyModel();
myModel.set({ obj1: { myAttribute1: \'abc\',myAttribute2: \'xyz\' } });
myModel.set(\'obj1\',{ myAttribute1: 123,myAttribute2: 456 });
在初始化时自动生成模型列表会很容易,但是这个解决方案对我来说已经足够了。     ,        Domenic提出的解决方案有一些缺点。假设您想收听\'change \'事件。在这种情况下,不会启动\'initialize \'方法,并且您的属性自定义值将被服务器中的json对象替换。在我的项目中,我遇到了这个问题。我的解决方案来覆盖Model的'set \'方法:
set: function(key,val,options) {
    if (typeof key === \'object\') {
        var attrs = key;
        attrs.content = new module.BaseItem(attrs.content || {});
        attrs.children = new module.MenuItems(attrs.children || []);
    }

    return Backbone.Model.prototype.set.call(this,key,options);
},
    ,        尽管在某些情况下使用Backbone模型代替嵌套的Object属性是合理的,如Domenic所述,但在更简单的情况下,您可以在模型中创建setter函数:
var MyModel = Backbone.Model.extend({
    defaults: {
        obj1 : {
            \"myAttribute1\" : false,\"myAttribute2\" : true,}
    },setObj1Attribute: function(name,value) {
        var obj1 = this.get(\'obj1\');
        obj1[name] = value;
        this.set(\'obj1\',obj1);
    }
})
    ,        如果与后端交互,则需要具有嵌套结构的对象。 但是有了骨干,线性结构就更容易工作了。 bone.linear可以为您提供帮助。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?