Вызов обработчика jQuery document.ready с применением метода? - PullRequest
2 голосов
/ 08 июня 2011

Ниже приведен код, который я использую в проекте с некоторыми сложными зависимостями. Убедившись, что все зависимости загружены, я запускаю onReadyCallback () , также приведенную ниже. У меня два вопроса:

  1. Правильно ли использовать anonymousHandler.apply (MyNameSpace) метод apply для анонимного обработчика, вызываемого для Document.ready
  2. Из того, что я понимаю, поскольку я использую метод apply, анонимная функция будет запускаться немедленно независимо от состояния готовности документа. Тогда как я могу передать в контексте MyNameSpace anonymousHandler , чтобы "this" внутри функции ссылалось на MyNameSpace

    var onReadyCallback = function(){
        jQuery(document).ready(function(){
           if(!this.loggedIn()){
              return;
           }
           ...Lots of Code referring to MyNameSpace using "this"
    
        }.apply(MyNameSpace));
    };
    
    //load the additional files that are needed and fire onReadyCallback
    MyNameSpace.Util.loadFiles(defaultJsFiles,function(){ 
        MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
           onReadyCallback.apply(window);          
        });
    });
    

Ответы [ 2 ]

4 голосов
/ 08 июня 2011

Как насчет этого, используя анонимную функцию и call?

jQuery(document).ready(function() {
    (function() {
        // this == MyNamespace
    }).call(MyNamespace);
});
1 голос
/ 08 июня 2011

Обычно функция jQuery события ready вызывается следующим образом:

$(function() { /* ... */ });
// or 
jQuery(function() { /* ... */ });
// or
jQuery(document).ready(function() { /* ... */ });

Суть в том, что функции не присвоен конкретный контекст;фактический контекст, заданный функцией jQuery, является элементом HTMLDocument, независимо от аргумента (в последнем примере, document).Почему это так, это другой предмет.

Обычно каждая из этих функций вызывается позже, после того, как все загружено, но не обязательно.В вашем случае есть ссылка на MyNameSpace до того, как произойдет событие ready.Даже если Javascript является языком типа LALR , и он найдет символ, объявленный позже, это не очень хорошая практика.Что если позже MyNameSpace будет установлен на что-то другое, прежде чем jQuery вызовет функции обратного вызова ready?Ваш ready обратный вызов не получит эту новую ссылку.Если нет преднамеренного, ссылка должна быть сделана внутри обратного вызова ready, когда все ... готово.

Затем внутри обратного вызова ready существуют другие методы дляназначить контекст для функции. loneomeday в значительной степени дали правильный способ выполнить то, что вы пытаетесь сделать.

(function() {
    // this == MyNamespace
}).call(MyNamespace);

Приведенный выше код выполняет анонимную функцию сразу, где this == MyNameSpace

примечание : разница между применяется и вызов расшифровывается здесь

Теперь идет нижняя частькод, который вы указали:

//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){ 
    MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
       onReadyCallback.apply(window);          
    });
});

Это проблематично и не нужно.Нужна ли там только функция onReadyCallback или она будет вызываться несколько раз?Если его нужно вызывать только один раз, сэкономьте глобальное пространство имен и просто сделайте:

//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){ 
    MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){

       // if everything is done loading, the function will be executed, otherwise
       // it's execution will be postponed later
       jQuery(function() {

           // create our nicely wrapped anonymous function now
           (function() {
              if(!this.loggedIn()){
                 return;
              }
              // ...Lots of Code referring to MyNameSpace using "this"

           })(MyNameSpace);  // grab our most recent reference of `MyNameSpace`

       });
    });
});

Если вам не нравится отступ (это просто вкус разработчика), замените все в readyобратный вызов с (что-то вроде):

 initMyNameSpace.apply(MyNameSpace);

и создание вашей функции снаружи, в глобальном пространстве:

 function initMyNameSpace() {
    if(!this.loggedIn()){
       return;
    }
    // ...Lots of Code referring to MyNameSpace using "this"

 };

Но я бы рекомендовал, по крайней мере, поместить ее в require функция обратного вызова, так что ...

  1. ... не загрязняет глобальное пространство имен функцией однократного выполнения
  2. ... нигде не доступен (сохраните ееprivate)
  3. ... можно быстро найти при редактировании исходного кода
  4. и т. д.

note : обычно apply и call используются, чтобы избежать повторного доступа к объектам, таким как some.thing.pretty.deep = value; или когда одна функция должна быть применена ко многим, но не ко всем объектам, и, таким образом, расширение прототипа объекта просто не очень хорошая идея.

В любом случае, это мое мнение, и как бы я поступил безбольше знаний о вашем коде или о том, что вы делаете.

...