天天看點

AngularJS —— 使用子產品組織你的代碼 【已翻譯100%】(2/3)

函數是一個對象:它建立了範圍

這是因為現在你已經把isdoingwork這個變量建立在了一個函數裡面 -- 也就是我們們的匿名 iife 中 -- 而如此這個變量就隻能通過這個函數才能通路到. 有趣的是javascript中的所有函數都是第一類對象. 那很簡明的意味着函數是一個對象,它可能通過一個變量被通路到. 或者說,另外一種描述的方式是你存儲了指向 函數的一個引用,并在稍後的某個時間擷取其變量.

在我們第一個示例中,我們的問題是并沒有儲存一個指向我們匿名函數的引用,是以我們永遠也不能再擷取到isdoingwork這個值。這就是我們下一個示例要改進的地方.

函數是一個對象 : 使用this

因為每一個函數都是一個對象,是以每個函數都會有一個this變量,這個變量向開發者提供了指向目前對象的引用. 為了提供在從外部大我們的函數及其範圍的通路,我們可以傳回這個this變量 -- 而它将會提供一個指向目前對象的引用.

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

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

在第二行我們也已經将isdoingwork加入了this引用中,那樣我們就可以使用文法thing.isdoingwork來從外部引用到這個值了.

自己動手看看

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

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

2.在你的浏覽器中打開 modulepattern4.htm.

3.打開浏覽器開發工具 -- f12(chrome, ie) 或者 ctrl-shift-i (opera) -- (那樣你就可以看到控制台了)

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

5.不過,現在你得輸入thing.isdoingwork才能或者這個值.

子產品模式總結

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

最終,我們用上了 angularjs

因為使用子產品模式是一個最佳實踐,angularjs的開發者就将一個子產品系統建構到了庫中.

plunker 代碼

而我們在這裡展示出代碼,那樣我們就可以更友善的談論它了.

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

angular 指令 : ng-app

angular 所定義和使用的東西叫做指令。這些指令基本上就是由angular定義屬性,而angularjs編譯器(angular的javascript)會将它們轉換成其他的東西.

我們應用了ng-app指令,為我們的angular應用定義了一個名稱,叫做mainapp.

mainapp 就是我們稍後會看到的子產品模式的起點.

被引入的腳本 : 每個都是一個子產品

現在,請注意有三個腳本被引入到了這個html中.

第一個是必須的angularjs庫.

而其他兩個則是作為子產品被實作的angular控制器.

它們被作為子產品實作以保持代碼彼此,還有從這個應用上看,都是獨立的.

angularjs : 建立 score

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

這是在為div的每一個都設定上ng-controller. 這些div中的每一個都有其各自的範圍. 第一個控制器的名字叫做 mainctrl,第二個叫做 secondctrl.

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

如果angularjs編譯器沒有找個這兩個名稱對應的函數,它就會抛出一個錯誤.

mainctrl.js : 第一個控制器

讓我們來看看mainctrl.js檔案裡面有些啥東西.

你可以在plunker頁面的左側點選它在plunker中将其打開.

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

那是因為我們需要這些代碼在檔案mainctrl.js被加載時就運作.

現在,請注意在這個iife中的第一行代碼.

這行代碼是angular将一個子產品添加到其命名空間的方式. 在這裡,我們添加了一個将用來展示我們應用程式的子產品. 這是應用程式的子產品,而我們已經将其命名為 itmainapp, 它跟html頁面上ng-app所指定的值是一樣的.

我們也建立了一個叫做app的(隻在iife本地可見的)本地變量,以便我們将可以在這個函數内部用來再次添加一個控制器.

奇怪的 angular 文法

請你也要再仔細看看第一行。你會注意到我們是首次建立mainapp子產品,而如果是首次,則我們必須提供以字元串數組的形式提供其可能需要的任何依賴(,表示出依賴庫的名稱). 不過,在這裡對于這個簡單的示例而言,我們不需要任何的依賴。但angular仍然需要我們傳入一個空的數組,以便它知曉我們正在建立新的子產品,而不是去試圖加載一個已經被建立好了的子產品.

提示: 你将會看到我們會在secondctrl.js裡加載mainapp子產品,而上面所提的數組将會有更多的作用.

我們一把mainapp建立好,就需要向其添加我們的控制器. 這些就是angular預期我們在html(的div中)加入的控制器.

将控制器添加到app子產品

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

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

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

這裡,當我們的控制器運作時,會向控制台輸出一行. 然後,我們将this變量重命名為vt(友善起見,就叫他虛拟的this) ,而後我天為其添加了一個name屬性和一個叫做allthings 的字元串數組.

控制器和封裝

那就是當控制器被angular調用時會運作的代碼. 那個控制器會在檔案被加載時運作起來,也就是一開始html被加載的時候. 這意味着控制器會被加載到app子產品中,而這些屬性會被添加到控制器對象(函數)中。因為我們想this變量添加了屬性,我們就可以在稍後擷取這些屬性,但它們是被封裝了起來的,是以它們不可以被每個人随意的更改.

現在,讓我們跳到html中控制器被引用和使用的地方.

第一個div

這是我們的mainctrl控制器被引用和使用的第一個div。它看起來就像下面這樣:

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

AngularJS —— 使用子產品組織你的代碼 【已翻譯100%】(2/3)

繼續閱讀