2011-06-08 76 views
2

以下是我在具有一些複雜依賴項目的項目中使用的代碼。在確定所有的依賴已經被加載後,我會觸發下面給出的onReadyCallback()。我有兩個問題:使用apply方法調用jQuery document.ready處理程序?

  1. 是否正確使用,anonymousHandler.apply(myNameSpace對象)時,在一個匿名處理程序應用方法的要求的document.ready
  2. 據我瞭解,因爲我使用無論文檔的就緒狀態如何,匿名函數的apply方法都會立即觸發。然後,我怎麼能在了myNameSpace的情況下傳遞給anonymousHandler所以,「這」裏面的功能是指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);   
        }); 
    }); 
    
+1

我希望你的其他代碼看起來不像這樣。沒有冒犯... – 2011-06-08 16:33:41

+0

@ yanick-rochon :)爲什麼你覺得它太亂了?任何提示(博客文章,書籍或兩個)將不勝感激... – 2011-06-08 16:38:40

+0

因爲這個評論的答案需要一些發展,我給你的問題添加一個答案 – 2011-06-08 16:57:09

回答

4

這個怎麼樣,使用匿名函數和call

jQuery(document).ready(function() { 
    (function() { 
     // this == MyNamespace 
    }).call(MyNamespace); 
}); 
+0

謝謝,使用另一個匿名函數似乎解決了傳遞上下文的問題。 我還是比較新的javascript:我認爲,我假設anonymousHandler.apply(MyNameSpace)將立即啓動,無論文檔的準備狀態是正確的? – 2011-06-08 17:00:09

+0

是的,只要回調運行,它就會運行。 – lonesomeday 2011-06-08 17:05:58

1

通常,ready事件jQuery函數被調用這樣

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

底線,該函數沒有給出特定的上下文;無論參數如何(在最後一個示例中爲document),jQuery給該函數提供的實際上下文都是HTMLDocument元素。爲什麼這是另一個話題。

一般而言,每個函數都會在所有內容加載後調用,但並不是必需的。在你的情況下,ready事件發生之前有MyNameSpace的引用。即使Javascript是一個LALR類型的語言,它會找到稍後聲明的符號,但這不是一個好習慣。在jQuery觸發ready回調函數之前,MyNameSpace會在後面設置爲什麼?你的ready回調不會獲得新的參考。除非有意爲之,否則參考應在之內ready回撥,當一切都準備就緒時。

然後,在ready回調中,還有其他技術爲函數分配上下文。 lonesomeday幾乎給了正確的方式來完成你正在嘗試做的事情。

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

上面的代碼執行匿名函數向右走,在那裏this == MyNameSpace

之間的區別適用呼叫被描述下here

現在,自帶底部您提供的代碼:

//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. ...是不是從任何地方訪問全局命名空間(保持私營)
  3. ..編輯源代碼

時。可很快發現:通常情況下,適用調用用於避免重複訪問諸如some.thing.pretty.deep = value;之類的對象,或者需要將一個函數應用於許多但不是所有對象,從而擴展對象的原型不是一個好主意。

無論如何,這是我的看法,以及我將如何做事,而不需要更多關於代碼的知識或做什麼。

+0

非常感謝您抽出寶貴的時間寫出詳細的解釋,有一些非常有用的觀點/提示......肯定有助於加深我對這個東西的理解。 – 2011-06-08 18:36:20

相關問題