日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
AngularJS——使用模塊組織你的代碼

下載 modulePattern.zip - 所有的 4 個 HTML 文件  以及 panacea.js - 1.6 KB

站在用戶的角度思考問題,與客戶深入溝通,找到周寧網(wǎng)站設(shè)計與周寧網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、主機域名、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋周寧地區(qū)。

介紹

AngularJS 的庫里面有很多東西,但本文中我只想專注于小的,針對特定主題的庫,我相信通過它們能對Angular有一個較好的介紹.  理解這篇文章并不需要你有任何Angular相關(guān)的,甚至是JavaScript的經(jīng)驗。希望你能從本文中看到一些使用Angular的好處,并樂于動手嘗試.

背景

我使用Angular有一段時間了,而在學(xué)習(xí)Angular的時候,我也喜歡構(gòu)建一些樣例,所以當(dāng)我一開始深入進去的時候,對于模塊或者JavaScript的設(shè)計模式,我也沒有多想,那樣對保持代碼組織和條理性有幫助.  那就是所有的重點:保持代碼的組織和條理性.  因此,現(xiàn)在我回過頭來,創(chuàng)建了這個極其小巧的樣例,以展示使用模塊可以有多簡單.  一路走來,我希望它能夠成為一篇好的對Angular的介紹.

(大多數(shù))文章在闡述模式時的問題

大多數(shù)時候人們都會嘗試去在讀者知道模式是啥概念之前就開始闡述一個模式,而這基本上誤導(dǎo)了每一個人.  這里要努力使得本文盡量簡單,讓我們首先來看一看這個問題吧。哪個問題呢?就是有關(guān)默認會在全局內(nèi)存空間被創(chuàng)建的所有東西的Javascript的問題.

下面就是我所說的意思.

JavaScript 默認的全局問題

設(shè)想你的HTML中有下面這樣一段腳本.

 
 
  1.  

范圍?

你清楚這個變量的范圍么? 
是的,它是全局的。這個布爾值實際上被添加到了瀏覽器的全局窗口對象中.  

把它設(shè)置到Action中
 

這里你可以看到它在Action中是怎樣的.

  1. 下載本文的代碼樣例.

  2. 在你的瀏覽器中打開 modulePattern.htm .

  3. 打開瀏覽器開發(fā)工具 -- F12(Chrome, IE) or Ctrl-Shift-I (Opera) -- (那樣就可以看見控制臺了)

  4. 在瀏覽器工具控制臺下,輸入: isDoingWork,然后回車

  5. 你會看到輸出的值為false. 

  6. 現(xiàn)在輸入 : isDoingWork = true,然后回車

  7. 如此下載的值就為true了. 你已經(jīng)改變了這個值.

  8. 你可以看到這個值已經(jīng)通過輸入doingwindow.isDoingWork = true然后回車,被添加到了全局窗口對象之中. 

這可能會造成一些名字沖突,也會導(dǎo)致一些嚴(yán)重的bug. 這也許對你而言有點杞人憂天了,是不?  但是請設(shè)想你是決定要去實現(xiàn)某一個新的JS庫,它每分每秒都可以被創(chuàng)建出來.  假設(shè)你發(fā)現(xiàn)了這個叫做 Panacea.js 的很棒的庫,它將解決你所有的問題.

因此你向下面這樣在你的頁面中引用了它:

 
 
  1.  

如此簡單,你就已經(jīng)解決之前你遇到的所有問題. 然而,因為它是一個龐大的庫,而你只想要解決方法,卻不回去深挖這個龐大(幾千行代碼)源文件里的每一行代碼.  而深埋在 Panacea.js 里面某個角落的確實下面這樣的代碼:

 
 
  1. var isDoingWork = false;  
  2.    
  3. setInterval(function(){isDoingWork = !isDoingWork;}, 3000); 

這代碼真是酷,你知道嗎?

每個3秒,它都會將這個布爾值設(shè)置成相對的值。啊!

自己動手看看

如果你想要自己動手驗證下這個東西,你可以做下面這幾步:

  1. 下載本文的樣例代碼.

  2. 在你的瀏覽器中打開 modulePattern2.htm .

  3. 打開瀏覽器開發(fā)工具 -- F12(Chrome, IE) 或者 Ctrl-Shift-I (Opera) -- (這樣你就可以看到控制臺了)

  4. 在瀏覽器開發(fā)工具的控制臺下,輸入 : isDoingWork 然后回車

  5. 將第4步多重復(fù)幾次,你將會發(fā)現(xiàn)isDoingWork的值會每個大約3秒鐘變化一次.

那這是不是很棒呢?

我的***個觀點 : 模塊模式是很有用的

我需要為此做出解釋,為了要向你展示為什么 JavaScript 的模塊模式是很有用的.  我得想你展示 JavaScript 的模塊模式,那樣我就可以告訴你它是如何在AngularJS中被使用或?qū)崿F(xiàn)的了. 

模塊模式:封裝

如此,實際就是,模塊模式基本上就是封裝了.  封裝聽起來很熟悉,如果你有點面向?qū)ο缶幊探?jīng)歷的話 -- 而我也希望你能有點這個經(jīng)驗.  封裝是面向?qū)ο缶幊痰娜瓌t之一。封裝的另外一個說法就是數(shù)據(jù)隱藏。在經(jīng)典的面向?qū)ο缶幊讨小煌贘avaScript所依賴的原型化OOP -- 數(shù)據(jù)隱藏是構(gòu)建一個類模板的內(nèi)在組成部分.

例如在 C#中, Animal 類的封裝 -- 隱藏數(shù)據(jù) -- 特定的值被關(guān)聯(lián)到Animal對象. 那樣,如果某人決定變更那些值,他或他必須明確的通過初始化一個Animal對象并設(shè)置這個對象的值來達到目的.  在JavaScript中,我們則可以隨意的在全局窗口對象中設(shè)置值.

 
 
  1. public class Animal  
  2.    
  3. {  
  4.      // constructor allows user to set the commonName  
  5.      public animal(string name)  
  6.      {  
  7.         this.commonName = name;  
  8.      }  
  9.      // making commonName private hides (encapsulates) it in the class  
  10.      private string commonName;  
  11.      //explicitly exposing the value for reading only  
  12.      public string CommonName  get { return this.commonName    }  

在JavaScript中,模塊已經(jīng)被創(chuàng)建用來模擬這種封裝行為了,如此我們就不會去將我們的變量組織到一個全局的命名空間中,并造成了隱藏很深的難以被發(fā)現(xiàn)和修復(fù)的問題.

現(xiàn)在你知道為什么了,讓我們來看看如何會是這樣的.

函數(shù)被立即調(diào)用的表達式(IIFE)

看上去就好像每次我們向前推進一步,我們都要走點旁門左道.  因為要獲得能讓我們創(chuàng)建模塊模式的JavaScript語法,我們就得去了解一種叫做函數(shù)被立即調(diào)用的表達式語法,也叫做IIFE ( IIFE 發(fā)音是 "iffy").

最基礎(chǔ)的 IIFE 看起來像這樣:

 
 
  1. (function(){  
  2.    // lines  
  3.    // of  
  4.    // code  
  5. }()); 

如果你從來沒有看到過像這樣的東西,那你就有點說不過去了.

立即被調(diào)用

首先,這個名稱的***部分叫做立即被調(diào)用的原因是,一般包含這個特殊函數(shù)的源文件被加載好了,那么包含在這個函數(shù)中的代碼就會運行. 

對IIFE語法更加仔細的觀察

你可以看到這個語法的最中心是一個函數(shù)。看一下這個代碼塊,我已經(jīng)將代碼分段并將一些行標(biāo)上了號,如此我們就可以探討它了.

 
 
  1. ( // 1.  
  2.    function() //2.  
  3.    { // 3.  
  4.      // 一行一行  
  5.      // 的  
  6.      // 代碼  
  7.    }() // 4.  
  8. ); // 5. 

首先,看看上面腳本的第2行。這一行通常看來就是一個匿名(也就是沒有命名)的函數(shù)聲明.  而后,第3一直到第4則是這個函數(shù)的主題部分。***,第4行***以一對括弧結(jié)束,這對 括弧會告訴JavaScript解釋器去調(diào)用這個函數(shù)。最終, 所有這些都會被包在一個不歸屬任何部分的括?。ǖ?和第5行)中, 而這對括弧會告訴解釋器要調(diào)用這個外部的匿名函數(shù),它包含了我們所定義的函數(shù).

IIFE 可以帶上參數(shù)

這段奇怪的語法會在帶上參數(shù)之后,看起來會更加的奇怪.  它看起來會像是下面這樣

 
 
  1. (function(thing1, thing2){  
  2.    // lines  
  3.    // of  
  4.    // code  
  5. }("in string", 382)); 

現(xiàn)在,你可以看到這個函數(shù)可以帶上兩個會被內(nèi)部的函數(shù)引用的thing1, thing2參數(shù).  被傳入值,在示例中是 "in string" 和 382. 

現(xiàn)在我們理解了IIFE語法,讓我們來創(chuàng)建另外一個代碼示例,我們將運行這段代碼來看看封裝是如何運作的.

 
 
  1. (function(){  
  2.    var isDoingWork = false;  
  3.    console.log("isDoingWork value : " + isDoingWork);  
  4. }()); 

自己動手看看
 

為了看看是怎么運行的,你可以做下面這幾步:

  1. 下載本文的源代碼.

  2. 在你的瀏覽器中打開 modulePattern3.htm.

  3. 打開瀏覽器的開發(fā)工具 -- F12(Chrome, IE) 或者 Ctrl-Shift-I (Opera) -- (這樣你就可以看到控制臺了)

  4. 你可以看到很像下面這樣圖片中所展示出來的東西

當(dāng)方法被調(diào)用時 -- 這會在代碼被JavaScript解釋器加載支護立即發(fā)生 -- 而后函數(shù)會創(chuàng)建 isDoingWork 變量,并調(diào)用console.log()來在控制臺輸出這個變量的值.

現(xiàn)在,讓我們使用開發(fā)工具中的控制臺來試試我們之前所嘗試過的步驟:

  1. 輸入: isDoingWork然后回車

當(dāng)你這樣做了之后,你將會看到 瀏覽器不再相信isDoingWork這個值被定義過。即使是你嘗試從全局窗口對象中獲取這個值, 瀏覽器也不認為 isDoingWork 這個值在此對象中被定義了.  你所看到的錯誤消息看起來會像接下來這張圖片中所展示的這樣.

函數(shù)是一個對象:它創(chuàng)建了范圍

這是因為現(xiàn)在你已經(jīng)把isDoingWork這個變量創(chuàng)建在了一個函數(shù)里面 -- 也就是我們們的匿名 IIFE 中 -- 而如此這個變量就只能通過這個函數(shù)才能訪問到.  有趣的是Javascript中的所有函數(shù)都是***類對象. 那很簡明的意味著函數(shù)是一個對象,它可能通過一個變量被訪問到.  或者說,另外一種描述的方式是你存儲了指向 函數(shù)的一個引用,并在稍后的某個時間獲取其變量.

在我們***個示例中,我們的問題是并沒有保存一個指向我們匿名函數(shù)的引用,所以我們永遠也不能再獲取到isDoingWork這個值。這就是我們下一個示例要改進的地方.

函數(shù)是一個對象 : 使用this

因為每一個函數(shù)都是一個對象,所以每個函數(shù)都會有一個this變量,這個變量向開發(fā)者提供了指向當(dāng)前對象的引用. 為了提供在從外部大我們的函數(shù)及其范圍的訪問,我們可以返回這個this變量 -- 而它將會提供一個指向當(dāng)前對象的引用.

然后,除非我們將這個私有的isDoingWork變量添加到函數(shù)引用(this)上,我們也不能夠引用這個變量。為此我們要對之前的示例做一下輕微的改動。它看起來會像下面這樣:

 
 
  1. thing = (function(){  // 1.  
  2.    this.isDoingWork = false; // 2.  
  3.    console.log("isDoingWork value : " + isDoingWork);  
  4.    return this; // 3.  
  5. }()); 

你可以看到***行我們加入了一個新的全局變量thing,它包含了從匿名函數(shù)返回的值。從示例代碼的開頭跳到第三行,你可以看到我們返回了this變量。那就意味著我們返回了一個指向匿名函數(shù)的引用.

在第二行我們也已經(jīng)將isDoingWork加入了this引用中,那樣我們就可以使用語法thing.isDoingWork來從外部引用到這個值了.

自己動手看看

為了看看的運行,你可以做下面這幾步:

  1. 下載本文的示例代碼.

  2. 在你的瀏覽器中打開 modulePattern4.htm.

  3. 打開瀏覽器開發(fā)工具 -- F12(Chrome, IE) 或者 Ctrl-Shift-I (Opera) -- (那樣你就可以看到控制臺了)

  4. 你將會看到isDoingWork的值會輸出到控制臺,就像最開始那個示例中你看到的那樣.

  5. 不過,現(xiàn)在你得輸入thing.isDoingWork才能或者這個值. 

模塊模式總結(jié)
 

在***這個示例中,變量值被成功的封裝了,而其他的JavaScript庫則可以明確的引用thing對象來獲取這個值.  好像不大可能,而這幫助了我們保持全局命名空間的干凈,并且在看起看來是更好的代碼組織形式. 這也使得我們代碼的維護更容易.

#p#

最終,我們用上了 AngularJS

因為使用模塊模式是一個***實踐,AngularJS的開發(fā)者就將一個模塊系統(tǒng)構(gòu)建到了庫中.

Plunker 代碼

首先你可以通過到這個Plunker上 (http://plnkr.co/edit/js8rbKpIuAuePzLF2DcP?p=preview - 在一個新的窗口或Tab頁打開)獲取整個AngularJS示例.

而我們在這里展示出代碼,那樣我們就可以更方便的談?wù)撍?

首先,讓我們看看這個 HTML.  

 
 
  1.  
  2.  
  3.    
  4.    
  5.      
  6.     Angular Module Example 
  7.      
  8.      
  9.      
  10.    
  11.    
  12.    
  13.      
  14.       

    mc refers to MainCtrl which has   

  15.       been added to the angular app module

     
  16.       

    Hello {{mc.name}}!

     
  17.       
      {{a}}
     
  18.     
 
  •      
  •       

     

  •         Hello {{sc.name}}  
  •       

     
  •       
      {{a}}
     
  •     
  •  
  •    
  •    
  •  
  • Angular 指令 : ng-app
     

    Angular 所定義和使用的東西叫做指令。這些指令基本上就是由Angular定義屬性,而AngularJS編譯器(Angular的JavaScript)會將它們轉(zhuǎn)換成其他的東西.

    我們應(yīng)用了ng-app指令,為我們的Angular應(yīng)用定義了一個名稱,叫做mainApp.

    mainApp 就是我們稍后會看到的模塊模式的起點.  

    被引入的腳本 : 每個都是一個模塊

    現(xiàn)在,請注意有三個腳本被引入到了這個HTML中.

    ***個是必須的AngularJS庫.

    而其他兩個則是作為模塊被實現(xiàn)的Angular控制器.

    它們被作為模塊實現(xiàn)以保持代碼彼此,還有從這個應(yīng)用上看,都是獨立的.

    AngularJS : 創(chuàng)建 score
     

    在往下看,你將會看到兩個以如下代碼開頭的div:

     
     
    1.  
     
     
    1.  

    這是在為div的每一個都設(shè)置上ng-controller.  這些div中的每一個都有其各自的范圍.  ***個控制器的名字叫做 MainCtrl,第二個叫做 SecondCtrl.

     AngularJS 編譯器會在你提供(引入)的代碼中用這兩個名稱查找對應(yīng)的函數(shù).

    如果AngularJS編譯器沒有找個這兩個名稱對應(yīng)的函數(shù),它就會拋出一個錯誤.

    mainCtrl.js : ***個控制器

    讓我們來看看mainCtrl.js文件里面有些啥東西.

    你可以在Plunker頁面的左側(cè)點擊它在Plunker中將其打開.

    當(dāng)你打開了它,你將會看到一些看上去很熟悉的代碼。好吧,你至少會看出來它們都是被包在一個IIFE中的.

     
     
    1. (function() {  
    2.    
    3.   var app = angular.module('mainApp', []);  
    4.    
    5.   app.controller('MainCtrl', function() {  
    6.     console.log("in MainCtrl...");  
    7.     // vt = virtual this - just shorthand  
    8.     vt = this;  
    9.     vt.name = 'MainCtrl';  
    10.     vt.allThings = ["first", "second", "third"];  
    11.    
    12.   });  
    13. })(); 

    那是因為我們需要這些代碼在文件mainCtrl.js被加載時就運行.

    現(xiàn)在,請注意在這個IIFE中的***行代碼.

     
     
    1. var app = angular.module('mainApp', []); 

    這行代碼是Angular將一個模塊添加到其命名空間的方式.  在這里,我們添加了一個將用來展示我們應(yīng)用程序的模塊.  這是應(yīng)用程序的模塊,而我們已經(jīng)將其命名為 itmainApp, 它跟HTML頁面上ng-app所指定的值是一樣的.

    我們也創(chuàng)建了一個叫做app的(只在IIFE本地可見的)本地變量,以便我們將可以在這個函數(shù)內(nèi)部用來再次添加一個控制器.  

    奇怪的 Angular 語法

    請你也要再仔細看看***行。你會注意到我們是***創(chuàng)建mainApp模塊,而如果是***,則我們必須提供以字符串?dāng)?shù)組的形式提供其可能需要的任何依賴(,表示出依賴庫的名稱). 不過,在這里對于這個簡單的示例而言,我們不需要任何的依賴。但Angular仍然需要我們傳入一個空的數(shù)組,以便它知曉我們正在創(chuàng)建新的模塊,而不是去試圖加載一個已經(jīng)被創(chuàng)建好了的模塊.

    提示: 你將會看到我們會在secondCtrl.js里加載mainApp模塊,而上面所提的數(shù)組將會有更多的作用.

    我們一把mainApp創(chuàng)建好,就需要向其添加我們的控制器. 這些就是Angular預(yù)期我們在HTML(的div中)加入的控制器.

    將控制器添加到App模塊

    添加控制器的代碼看起來像下面這樣:

     
     
    1. app.controller('MainCtrl', function() {  
    2.     console.log("in MainCtrl...");  
    3.     // vt = virtual this - just shorthand  
    4.     vt = this;  
    5.     vt.name = 'MainCtrl';  
    6.     vt.allThings = ["first", "second", "third"];  
    7.    
    8.   }); 

    為了添加我們的控制器函數(shù),我們向app.controller()函數(shù)提供了一個控制器名稱和一個函數(shù). 在此處我們提供了一個匿名函數(shù).

    所以,我們的控制器主體代碼就是下面這幾行了:

     
     
    1. console.log("in MainCtrl...");  
    2.    // vt = virtual this - just shorthand  
    3.    vt = this;  
    4.    vt.name = 'MainCtrl';  
    5.    vt.allThings = ["first", "second", "third"]; 

    這里,當(dāng)我們的控制器運行時,會向控制臺輸出一行.  然后,我們將this變量重命名為vt(方便起見,就叫他虛擬的this) ,而后我天為其添加了一個name屬性和一個叫做allThings 的字符串?dāng)?shù)組.

    控制器和封裝

    那就是當(dāng)控制器被Angular調(diào)用時會運行的代碼. 那個控制器會在文件被加載時運行起來,也就是一開始HTML被加載的時候. 這意味著控制器會被加載到app模塊中,而這些屬性會被添加到控制器對象(函數(shù))中。因為我們想this變量添加了屬性,我們就可以在稍后獲取這些屬性,但它們是被封裝了起來的,因此它們不可以被每個人隨意的更改.

    現(xiàn)在,讓我們跳到HTML中控制器被引用和使用的地方.

    ***個Div

    這是我們的MainCtrl控制器被引用和使用的***個Div。它看起來就像下面這樣:

     
     
    1.  
    2.     

      mc refers to MainCtrl which has   

    3.     been added to the angular app module

       
    4.     

      Hello {{mc.name}}!

       
    5.     
        {{a}}
       
    6.  
     

    這個div輸出我們的web頁面的如下部分,看起來就是接下來這張圖片上所展示的那樣.

    輸出被使用Angular指令來創(chuàng)建
     

    不過,它使用了一種特殊的方式創(chuàng)建那個輸出,它使用了兩種Angular指令:

    1. {{mc.name}}

    2. ng-repeat

    ***個指令被關(guān)聯(lián)到了Div那一行上面MainCtrl的聲明和引用.  我們告訴Angular,說我們想以mc這個名稱引用我們的MainCtrl函數(shù)(對象)。那就是Angular提供的一個很棒的縮寫功能.

    現(xiàn)在,因為我們將一個屬性放到了MainCtrl的this對象上,我們現(xiàn)在就可以通過mc和屬性的名稱來引用那些東西了。我們將那些東西包含特殊的雙大括號{{ }}里面,如此Angular編譯器就懂得那是可以運行的代碼,你就會瞧見Angular將其轉(zhuǎn)換成了HTML:

     
     
    1. Hello {{mc.name}}!

       

    編程了下面這一:

    Hello MainCtrl!

    之后,我們設(shè)置了一個漂亮的無需列表,并使用了ng-repeat指令來迭代輸出數(shù)組中的每一行.

    然后Angular跌倒了整個allThings數(shù)組,并將其裝換成了下面的HTML

     
     
    1. {{a}}
    2.  

    變成了如下的輸出

    1. first
    2. second
    3. third

    就那么簡單。這就是模塊化的所有東西,我們的值再也不會被任何人動手動腳了.

    SecondCtrl : 幾乎就是同樣的東西

    這里有SecondCtrl的代碼. 代碼機會就是一樣的,除了我們獲取我滿原來的app模塊處有點不一樣——不是***次創(chuàng)建它了.

     
     
    1. (function() {  
    2.    
    3.   var app = angular.module('mainApp');  
    4.    
    5.   app.controller('SecondCtrl', function() {  
    6.     console.log("in SecondCtrl...");  
    7.     // vt = virtual this - just shorthand  
    8.     vt = this;  
    9.     vt.name = 'SecondCtrl';  
    10.     vt.allThings = ["bacon", "lettuce", "tomato"];  
    11.    
    12.   });  
    13. })(); 

    仔細看看下面這一行:

     
     
    1. var app = angular.module('mainApp'); 

    唯一的不同就是我們沒有提供引用數(shù)組.

    那是因為mainApp已經(jīng)是存在了的,而我們只是想向其添加另外一個新模塊 (SecondCtrl) .

    總結(jié):***實踐

    所有其它的腳本中的代碼,以及HTML基本上是一樣的,而此處最重要的是所有的代碼都被模塊化了,數(shù)據(jù)也被封裝了起來,以便更好的組織我們的代碼. 這是Google軟件開發(fā)者遵循的一個***實踐,也是我們應(yīng)該遵循的。請學(xué)習(xí)他,運用它,并與它同在吧(阿門). 

    英文:AngularJS: Organizing Your Code With Modules

    譯文:http://www.oschina.net/translate/angularjs-organizing-your-code-with-modules


    名稱欄目:AngularJS——使用模塊組織你的代碼
    轉(zhuǎn)載源于:http://www.5511xx.com/article/dpgiisg.html