Второй аргумент в .retrieve ();всегда работает? - PullRequest
0 голосов
/ 22 февраля 2012

Я экспериментировал с хранилищем элементов, и я озадачен проблемой с .retrieve(); в хранилище элементов.

В документации указано:

Элемент: retrieve фактически принимает необязательный второй параметр, который будет действовать как значение по умолчанию для сохранения, если другое значение ранее не существовало. Затем он получит значение, как ожидалось.

Основные примеры работают, но когда я создаю экземпляр Class во втором параметре, эта реализация запускается каждый раз, даже если я могу убедиться, что .retrieve(); возвращает объект Class, который был созданный ранее.

Relevent jsFiddle

Если вы посмотрите на скрипку, вы увидите, что каждый раз, когда вы нажимаете div, myClass снова создается. В идеале, его следует создать один раз, этот объект должен быть сохранен в хранилище элементов и надлежащим образом извлечен, чтобы предотвратить его повторное создание.

Вот как я звоню .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();
});

Любая подсказка, что вызывает такое поведение?

Ответы [ 3 ]

3 голосов
/ 22 февраля 2012

Второй аргумент всегда оценивается , да.В вашем случае новый экземпляр myClass создается при каждом вызове retrieve - это то, что вы видите в консоли.Это будет происходить всегда, независимо от результата вызова или фактической обработки параметра в методе (например, вы можете передать, например, еще 10 параметров в метод, все они будут оценены в момент вызова).

В вашем случае есть еще одно недоразумение: когда используется параметр по умолчанию для вызова retrieve, он не будет сохранен автоматически.Следовательно, ваш третий вариант на самом деле является правильным решением задачи

Получить значение для ключа 'foobar' - если значение не было установлено, создайте новый экземпляр myClass, сохраните его как 'foobar' и верните его.

(Обновлено - я ошибся в своем втором утверждении о состоянии, как @Julian H. Lam указал:второй параметр retrieve фактически сохраняется сразу.)

1 голос
/ 22 февраля 2012

К сожалению, это не сработает, как ожидалось - как заметил @Julian D., он всегда будет запускать new myClass()

. Альтернативный шаблон довольно популярен в mootools, который используется element.tween /морф и так далее, это выглядит так:

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/

Получатель - при запуске - вернет экземпляр из хранилища для вас, если он доступен, иначе он будетсоздайте его для себя и сохраните, а затем верните.

Чтобы создать экземпляр с пользовательскими параметрами, используйте element.set("myClass", { options }.

. Вы даже можете использовать это в новом конструкторе Element, например:

new Element("a", {
    myClass: {
        foo: "no bars for you"
    }
});

Приведенное выше создаст экземпляр myClass и сделает его доступным для элемента со свойством foo, являющимся настраиваемым.

Вот пример из реальной жизни, где я его использую: https://github.com/DimitarChristoff/mootstrap-button/blob/master/Source/mootstrap-button.js

и посмотрите документацию / пример здесь: https://github.com/DimitarChristoff/mootstrap-button/

0 голосов
/ 23 февраля 2012

Вы можете попробовать это

(function() {
  var def = new myClass();
  $('baz').addEvent('click', function() {
    this.retrieve('foobar', def).foo();
  });
}());

Таким образом, функция события уже создала экземпляр, поэтому при выполнении не будет создавать новые.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...