我一直在尝试元素存储,我对元素存储中.retrieve();
的问题感到困惑。
文档说明:
元素:retrieve实际上接受一个可选的第二个参数,如果以前不存在另一个值,它将作为存储的默认值。然后它将按预期检索该值。
基本示例有效,但是当我在第二个参数中实例化Class时,每次都会运行该实例化,即使我可以验证.retrieve();
是否正在返回Class
个对象那是先前实例化的。
如果您看一下小提琴,您可以看到每次单击div时,myClass都会再次实例化。理想情况下,它应该被实例化一次,该对象应该保存到Element存储中,并正确检索以阻止它再次被实例化。
这就是我打电话.retrieve();
的方式:
$('baz').addEvent('click', function() {
this.retrieve('foobar', new myClass()).foo();
});
...只是为了好玩,我试过这个(它也没用):
$('baz').addEvent('click', function() {
this.retrieve('foobar', (function() {
return new myClass();
})()).foo();
});
...这就是我最终通过不使用.retrieve()
的第二个参数来实现它的方式:
$('baz').addEvent('click', function() {
var instClass = this.retrieve('foobar');
if (instClass == null) {
instClass = this.store('foobar', new myClass()).retrieve('foobar');
}
instClass.foo();
});
有什么迹象导致这种行为?
答案 0 :(得分:3)
第二个参数总是得到评估,是的。在您的情况下,myClass
的新实例将在每次retrieve
调用时实例化 - 这就是您在控制台中看到的内容。这将始终发生,无论调用的结果或参数是否在方法中实际处理(您可以将10个参数传递给方法,它们都将在调用时得到评估)。
在您的情况下,还有另一个误解:当使用 retrieve
调用的默认参数时,它不会自动存储。因此,您的第三个变体实际上是正确的任务解决方案
<击>
检索键'foobar'的值 - 如果没有设置值,则创建一个新值
myClass
的实例,将其存储为“foobar”并将其返回。
(更新 - 我的第二个州陈述错了,因为@Julian H. Lam指出:retrieve
的第二个参数实际上是立即存储的。)
答案 1 :(得分:1)
不幸的是,这不会按预期工作 - 正如@Julian D.指出的那样,它将始终运行new myClass()
替代模式在mootools中非常流行,由element.tween / morph等使用,如下所示:
var myClass = new Class({
Implements: [Options],
options: {
foo: "bar"
},
initialize: function(element, options) {
console.log('I have been initialized!');
this.setOptions(options);
},
foo: function() {
console.log(this.options.foo);
}
});
Element.Properties.myClass = {
set: function(options){
this.get('myClass').setOptions(options);
return this;
},
get: function(){
var instance = this.retrieve('myClass');
if (!instance){
instance = new myClass(this);
this.store('myClass', instance);
}
return instance;
}
};
$('baz').addEvent('click', function() {
this.get('myClass').foo();
});
http://jsfiddle.net/dimitar/R7qFA/2/
getter - 运行时 - 将为您返回存储中的实例(如果可用),否则,它将为您创建一个并存储它,然后将其返回。
要使用自定义选项创建实例,请使用element.set("myClass", { options }
。
您甚至可以在新的Element构造函数中使用它,如下所示:
new Element("a", {
myClass: {
foo: "no bars for you"
}
});
上面将创建myClass的一个实例,并使其可用于foo属性为custom的元素。
这是我在现实生活中使用它的一个例子: https://github.com/DimitarChristoff/mootstrap-button/blob/master/Source/mootstrap-button.js
并在此处查看文档/示例: https://github.com/DimitarChristoff/mootstrap-button/
答案 2 :(得分:0)
你可以试试这个
(function() {
var def = new myClass();
$('baz').addEvent('click', function() {
this.retrieve('foobar', def).foo();
});
}());
这样,事件函数已经实例化了实例,因此在执行时不会创建新实例。