Когда вызывать YUI уничтожить? - PullRequest
1 голос
/ 29 сентября 2011

Когда следует называть уничтожение?Это когда-либо вызывается автоматически жизненным циклом YUI?Вызывает ли выгрузка страницы жизненный цикл YUI для вызова уничтожения всех объектов, созданных во время обработки страницы?Я работал в предположении, что мне нужно делать все свои собственные вызовы для уничтожения, но это становится проблематичным, когда вызовы ajax заменяют фрагменты кода, которые я постепенно улучшал.Например:

<div id="replaceMe">
  <table>
    <tr>
      <td>1</td>
    </tr>
    <tr>
      <td>2</td>
    </tr>
  </table>
  <script>
    YUI().use('my-lib', function(Y) {
      Y.mypackage.enhanceTable("replaceMe");
    });
  <script>
</div>

Модуль my-lib в основном добавляет обработчик щелчков и указатель мыши для каждой строки:

YUI.add('my-lib', function(Y) { 
    function EnhancedTable(config) {
        EnhancedTable.superclass.constructor.apply(this, arguments);
    }
    EnhancedTable.NAME = "enhanced-table";
    EnhancedTable.ATTRS = {
        containerId : {},
        onClickHandler : {},
        onMouseoverHandler : {},
        onMouseoutHandler : {}
    };
    Y.extend(EnhancedTable, Y.Base, {
        _click : function(e) {
            //... submit action
        },
        destructor : function() {
            var onClickHandler = this.get("onClickHandler"),
            onMouseoverHandler = this.get("onMouseoverHandler"),
            onMouseoutHandler = this.get("onMouseoutHandler");

            onClickHandler && onClickHandler.detach();
            onMouseoverHandler && onMouseoverHandler.detach();
            onMouseoutHandler && onMouseoutHandler.detach();
        },
        initializer : function(config) {
            var container = Y.one("[id=" + this.get("containerId") + "]");

            this.set("container", container);
            this.set("onMouseoverHandler", container.delegate("mouseover",
                    this._mouseover, "tr", this ));
            this.set("onMouseoutHandler", container.delegate("mouseout",
                    this._mouseout, "tr", this ));
            this.set("onClickHandler", container.delegate("click", 
                    this._click, "tr", this ));
        },
        _mouseout : function(e) {
            e.currentTarget.removeClass("indicated");
        },
        _mouseover : function(e) {
            e.currentTarget.addClass("indicated");
        }
    });

    Y.namespace("mypackage");
    Y.mypackage.enhanceTable = function(containerId) {
        var enhancedTable new EnhancedTable({containerId:containerId});
    };
}, '0.0.1', {
    requires : [ 'base', 'node' ]
});

Обработчик щелчков отправит запрос обратно в мое приложение, которое будетизменить страницу.Нужно ли мне помнить все расширенные объекты и иметь обработчик onunload, вызывающий метод уничтожения каждого?Или инфраструктура YUI позаботится об этом?

Последняя часть этого вопроса состоит в том, что у меня также есть код вне этого, который заменяет всю таблицу, заменяя содержимое <div id="replaceMe">.При этом скрипт будет перезапущен и дополнит новый <table> новым EnhancedTable.Нужно ли помнить старую таблицу и уничтожать ее до того, как новая таблица захлопнет ее?

1 Ответ

4 голосов
/ 29 сентября 2011

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

this._handlers = [ 
    container.delegate("mouseover", this._mouseover, "tr", this ),
    container.delegate("mouseout", this._mouseout, "tr", this ),
    container.delegate("click", this._click, "tr", this )
];

Затем добавлял бы метод деструктора, который выполняет следующие действия:

destructor : function() {
    new Y.EventTarget(this._handlers).detach();
}

Он выполняетто же самое, но с гораздо меньшим количеством работы с вашей стороны!

В идеале, вместо того, чтобы запускать это для каждой таблицы, вы должны прикрепить всех своих делегатов к #replaceMe, чтобы вам не нужно было каждый раз создавать зановоизменил содержимое, независимо от того, откуда это произошло.

YUI не будет автоматически вызывать .destroy() для вас при выгрузке, но будет очищать подпрограммы DOM.Вышесказанное является дополнительным кредитом, который действительно необходим, только если вы собираетесь уничтожить объект самостоятельно.

...