Javascript Backbone.js视图的默认值?
我在Javascript Backbone.js视图的默认值?,javascript,backbone.js,Javascript,Backbone.js,我在Backbone.js中工作,我想知道您是否可以像设置模型的默认值那样设置默认值 对于主干网1.1或更新版本 方法A:OptionsInLiteral,在initialize中带有u0.defaults 方法B:使用viewOptions插件(或类似插件) 感谢@BraveDave在评论中指出这一点 对于1.1版之前的主干(历史参考,仅供参考) 核心团队似乎最有可能摆脱这个。选项和中的逻辑一起配置 使用选项属性并始终使用此选项 在这个问题上有很多困惑,甚至是一个被高度评价和接受的错误答案。
Backbone.js中工作,我想知道您是否可以像设置模型的默认值那样设置默认值 对于主干网1.1或更新版本
方法A:OptionsInLiteral,在initialize中带有u0.defaults
方法B:使用viewOptions插件(或类似插件)
感谢@BraveDave在评论中指出这一点
对于1.1版之前的主干(历史参考,仅供参考)
核心团队似乎最有可能摆脱这个。选项
和中的逻辑一起配置
使用选项属性并始终使用此选项
在这个问题上有很多困惑,甚至是一个被高度评价和接受的错误答案。希望这个答案能够证明一个真正正确的解决方案,并指出所有其他候选答案中的错误
要与主干.View
父类协调工作,您应该包括传递给主干.View.extend的对象文本的选项
属性
var OptionsInLiteral = Backbone.View.extend({
options: {flavor: "vanilla"},
initialize: function (options) {
console.log("OptionsInLiteral.initialize first argument", options);
console.log("OptionsInLiteral.initialize this.options", this.options);
}
});
var OptionsInLiteral = Backbone.View.extend({
options: {flavor: "vanilla"},
initialize: function (options) {
console.log("OptionsInLiteral.initialize first argument", options);
console.log("OptionsInLiteral.initialize this.options", this.options);
}
});
下面是一些示例以及它们登录到控制台的内容
new OptionsInLiteral();
//OptionsInLiteral.initialize first argument undefined
//OptionsInLiteral.initialize this.options Object {flavor: "vanilla"}
new OptionsInLiteral({flavor: "chocolate"});
//OptionsInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsInLiteral.initialize this.options Object {flavor: "chocolate"}
new OptionsInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsInLiteral.initialize this.options Object {flavor: "strawberry", sprinkles: true}
new OptionsFunctionInLiteral();
//OptionsFunctionInLiteral.initialize first argument undefined
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "vanilla", created: "Wed Jun 19 2013 16:20:16 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "chocolate"});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "chocolate", created: "Wed Jun 19 2013 16:21:17 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "strawberry", created: "Wed Jun 19 2013 16:22:26 GMT-0600 (MDT)", collection: Backbone.Collection, sprinkles: true}
new OptionsInLiteral();
//OptionsInLiteral.initialize first argument undefined
//OptionsInLiteral.initialize this.options Object {flavor: "vanilla"}
new OptionsInLiteral({flavor: "chocolate"});
//OptionsInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsInLiteral.initialize this.options Object {flavor: "chocolate"}
new OptionsInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsInLiteral.initialize this.options Object {flavor: "strawberry", sprinkles: true}
new OptionsFunctionInLiteral();
//OptionsFunctionInLiteral.initialize first argument undefined
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "vanilla", created: "Wed Jun 19 2013 16:20:16 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "chocolate"});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "chocolate", created: "Wed Jun 19 2013 16:21:17 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "strawberry", created: "Wed Jun 19 2013 16:22:26 GMT-0600 (MDT)", collection: Backbone.Collection, sprinkles: true}
这将正确利用主干.View.\u configure
,从主干1.0.0开始如下所示:
_configure: function(options) {
if (this.options) options = _.extend({}, _.result(this, 'options'), options);
_.extend(this, _.pick(options, viewOptions));
this.options = options;
},
_configure: function(options) {
if (this.options) options = _.extend({}, _.result(this, 'options'), options);
_.extend(this, _.pick(options, viewOptions));
this.options = options;
},
scope.MyView = Backbone.View.extend({
x: {
a: 'a',
}
})
var obj = new scope.MyView({
x: {
b: 'b',
}
});
console.log( this.options );
// output: { x: { b:'b' } }
这意味着:
- 如果视图对象文字包含
选项
,\u configure
将正确地将其视为默认值,用传递到构造函数的属性覆盖它们,并将最终生成的对象设置为this.options
。万岁。这就是我们想要的
- 即使在没有参数的情况下调用视图构造函数,这也会起作用。万岁。这也是我们想要的
- 由于此处使用了
.result
,因此选项
属性可以是对象
或函数
,如果它是函数,将调用它并使用返回值
这也是可以接受的,并允许每个实例的默认值是唯一的
var OptionsFunctionInLiteral = Backbone.View.extend({
options: function () {
return {
flavor: "vanilla",
created: Date(),
collection: new Backbone.Collection()
};
},
initialize: function (options) {
console.log("OptionsFunctionInLiteral.initialize first argument", options);
console.log("OptionsFunctionInLiteral.initialize this.options", this.options);
}
});
var OptionsFunctionInLiteral = Backbone.View.extend({
options: function () {
return {
flavor: "vanilla",
created: Date(),
collection: new Backbone.Collection()
};
},
initialize: function (options) {
console.log("OptionsFunctionInLiteral.initialize first argument", options);
console.log("OptionsFunctionInLiteral.initialize this.options", this.options);
}
});
下面是一些示例以及它们登录到控制台的内容
new OptionsInLiteral();
//OptionsInLiteral.initialize first argument undefined
//OptionsInLiteral.initialize this.options Object {flavor: "vanilla"}
new OptionsInLiteral({flavor: "chocolate"});
//OptionsInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsInLiteral.initialize this.options Object {flavor: "chocolate"}
new OptionsInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsInLiteral.initialize this.options Object {flavor: "strawberry", sprinkles: true}
new OptionsFunctionInLiteral();
//OptionsFunctionInLiteral.initialize first argument undefined
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "vanilla", created: "Wed Jun 19 2013 16:20:16 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "chocolate"});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "chocolate", created: "Wed Jun 19 2013 16:21:17 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "strawberry", created: "Wed Jun 19 2013 16:22:26 GMT-0600 (MDT)", collection: Backbone.Collection, sprinkles: true}
new OptionsInLiteral();
//OptionsInLiteral.initialize first argument undefined
//OptionsInLiteral.initialize this.options Object {flavor: "vanilla"}
new OptionsInLiteral({flavor: "chocolate"});
//OptionsInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsInLiteral.initialize this.options Object {flavor: "chocolate"}
new OptionsInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsInLiteral.initialize this.options Object {flavor: "strawberry", sprinkles: true}
new OptionsFunctionInLiteral();
//OptionsFunctionInLiteral.initialize first argument undefined
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "vanilla", created: "Wed Jun 19 2013 16:20:16 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "chocolate"});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "chocolate"}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "chocolate", created: "Wed Jun 19 2013 16:21:17 GMT-0600 (MDT)", collection: Backbone.Collection}
new OptionsFunctionInLiteral({flavor: "strawberry", sprinkles: true});
//OptionsFunctionInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
//OptionsFunctionInLiteral.initialize this.options Object {flavor: "strawberry", created: "Wed Jun 19 2013 16:22:26 GMT-0600 (MDT)", collection: Backbone.Collection, sprinkles: true}
为什么您应该始终使用此选项
因此,上面的内容很好,但需要注意的是,如果在调用视图的构造函数时没有参数,则在initialize
函数中选项将存在并且是正确的,但是initialize
函数的普通选项参数将是未定义的
initialize: function (options) {
console.log(options.flavor); //BUG! options is undefined. Uncaught exeption. :-(
console.log(this.options); //correct
}
initialize: function (options) {
console.log(options.flavor); //BUG! options is undefined. Uncaught exeption. :-(
console.log(this.options); //correct
}
因此,当我定义initialize时,我甚至没有为函数指定options
参数来提醒不要使用它。通常,您希望忽略初始化
的选项
参数,因为它不包含默认值
错误的答案:u.extend(this.defaults,this.options)
这个答案有一个缺陷,它在每次实例启动时都会无意中修改所有未来实例的默认值
var DefaultsExtendView = Backbone.View.extend({
defaults: {flavor: "vanilla"},
initialize: function (options) {
console.log("initialize 1st argument", options);
this.options = _.extend(this.defaults, this.options);
console.log("initialize this.options", this.options);
}
});
new DefaultsExtendView(); //OK
new DefaultsExtendView({flavor: "chocolate"}); //OK
new DefaultsExtendView(); //BUG! You get chocolate instead of vanilla
var DefaultsExtendView = Backbone.View.extend({
defaults: {flavor: "vanilla"},
initialize: function (options) {
console.log("initialize 1st argument", options);
this.options = _.extend(this.defaults, this.options);
console.log("initialize this.options", this.options);
}
});
new DefaultsExtendView(); //OK
new DefaultsExtendView({flavor: "chocolate"}); //OK
new DefaultsExtendView(); //BUG! You get chocolate instead of vanilla
错误答案:if(options.foo)
注意选项对象和实例特定的默认值
这个问题的一个答案表明:
var DefaultsView = Backbone.View.extend({
defaults: {
collection: new Backbone.Collection()
},
initialize: function () {
_.defaults(this.options, this.defaults);
var DefaultsView = Backbone.View.extend({
defaults: {
collection: new Backbone.Collection()
},
initialize: function () {
_.defaults(this.options, this.defaults);
这几乎肯定不是你想要的,而且是一个bug。如果创建10个视图,它们将共享同一个Backbone.Collection
实例,因为定义视图子类时只创建1个实例。当您将模型添加到view9的集合中并在所有视图中显示时,这肯定会让您感到困惑。您更可能需要的是为每个视图实例创建一个不同的新集合实例,要获得该实例,您需要将options
作为一个函数,如上面的示例所示
总结正确的方法来做到这一点
使用选项:{…}
或选项:函数(){…}
声明您的初始化
,不带任何参数
以this.options
示例样板
工作桥
您可以在初始化功能中设置默认值
defaults: {
display: 'list'
},
initialize: function() {
this.options = _.extend({}, this.defaults, this.options);
}
这将适用于普通选项,但不会覆盖任何特殊选项(主干存储在视图对象上的选项-[“模型”、“集合”、“el”、“id”、“属性”、“类名”、“标记名”]
)
请看一个正在运行的演示:由主干网提供。它显示了视图的说明
构造函数/初始化视图([选项])
创建新视图时,传递的选项将附着到
将此选项查看为,以供将来参考。有几种特殊的
如果传递,将直接附加到视图的选项:模型,
集合、el、id、类名、标记名和属性。如果视图
定义一个初始化函数,该函数将在打开视图时调用
首先创建。如果要创建引用
元素已在DOM中,请将该元素作为选项传入:new
视图({el:existingElement})
我想知道为什么在视图中使用默认值的方式与在模型和集合中使用的方式不同。一种尝试。
来自主干网的源代码:
var View = Backbone.View = function(options) {
this.cid = _.uniqueId('view');
this._configure(options || {});
this._ensureElement();
this.initialize.apply(this, arguments);
this.delegateEvents();
};
我们将覆盖\u配置:
// Save _configure method
var _oldConfigure = Backbone.View.prototype._configure;
Backbone.View.prototype._configure = function(options){
_.defaults(options, this.defaults);
_oldConfigure.call(this, options);
};
现在,Backbone.View在默认值方面与Backbone.model的行为相同,您甚至不需要在构造函数/初始化方法中执行任何操作。正确的解决方案与dira的类似。仅在视图等级库中指定选项对象将包含选项对象的默认值:
查看源代码。\u配置以获取更多信息:适用于主干网1.1或更高版本
方法A:OptionsInLiteral,在initialize中带有u0.defaults
方法B:使用viewOptions插件(或类似插件)
https://github.com/rotundasoftware/backbone.viewOptions
感谢@BraveDave在评论中指出这一点
对于1.1版之前的主干(历史参考,仅供参考)
看起来像是核心的地方
var myView = Backbone.View.extend({
foo: "default_value",
initialize: function(options) {
if(options.foo) {
foo = options.foo;
}
}
});
new myView(); //BUG! options is undefined, uncaught exception
//TypeError: Cannot read property 'foo' of undefined
var DefaultsView = Backbone.View.extend({
defaults: {
collection: new Backbone.Collection()
},
initialize: function () {
_.defaults(this.options, this.defaults);
var MyView = Backbone.View.extend({
options: {flavor: "vanilla"},
initialize: function () { //note no declared arguments
//use this.options here as needed and all is well
}
});
MyScope.MyView = Backbone.View.extend({
options: {
default_prop: 'value1',
another_default: 'value2'
}
}
scope.MyView = Backbone.View.extend({
x: 'x',
})
var obj = new scope.MyView({
y: 'y',
});
console.log( this.options );
// output: { x: 'x', y:'y' }
scope.MyView = Backbone.View.extend({
x: {
a: 'a',
}
})
var obj = new scope.MyView({
x: {
b: 'b',
}
});
console.log( this.options );
// output: { x: { b:'b' } }
// Add the view options plugin functionality to all our views.
Backbone.ViewOptions.add( Backbone.View.prototype );
MyView = Backbone.View.extend( {
options : [
"type", // normal options are declared like so
{ "label" : "OK" } // options with defaults are declared like so
],
initialize : function( options ) {
this.setOptions( options ); // attaches declared options to the view
console.log( this.label ); // outputs "OK"
console.log( this.type ); // outputs "button"
}
} );
new MyView( { type : "button" } );