當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
AngularJS之禅
生活随笔
收集整理的這篇文章主要介紹了
AngularJS之禅
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
AngularJS是客戶端MVC框架,它運行在web瀏覽器中,有助于我們寫單頁面、AJAX風格的web應用,是一個通用的框架。 ? AngularJS速成 實例:Hello World 首先引用AngularJS庫angular.js。使用自定義的ng-app的HTML屬性來運行。仔細觀察<body>標簽,有另一個非標準的HTML屬性:ng-init,渲染模版前使用ng-init來初始化model。 AngularJS模版系統重要特性: 使用自定義HTML標簽和屬性為靜態html文檔添加動態行為 使用雙大括號{{}}輸出模型值 AngularJS中,框架理解和解釋的所有特別的HTML標簽和屬性都可以稱為指令。
雙向數據綁定 不需要刷新模板,不需要使用框架API來更新模型,AngularJS可以智能檢測模型變化且相應的更新DOM,任何視圖的變化都會立刻反應到模型中,任何模型的變化也會反應到模版上。 ? AngularJS中的MVC模式 Scope scope對象是提供模型給視圖(模板)。通過將屬性賦值給scope的實例,可以生成新值來渲染模板。對于給定視圖,scope能夠用數據和特定的功能來擴充??梢酝ㄟ^在scope實例上定義功能提供具體的UI邏輯給模板。 例如可以為name變量創建一個getter函數: 可以在模版中使用函數: scope使我們能夠精確控制domain模型的哪部分、哪些操作對視圖層可用。 ? Controller 主要職責是初始化scope對象。具體包括: 提供初始模型值 通過UI交互(函數)來擴充scope controller是正常的js功能函數。沒有擴展任何具體框架類,不調用任何特定的AngularJS的api來執行操作,也不操作html模板和dom。 ? Model 僅是js的對象,不繼承任何框架基類,不以任何特別方式構建模型對象。為了提供模型給AngularJS,僅需要將模型賦值給scope。 ? 深入理解scope 每個$scope是Scope類的實例,Scope類有方法控制scope生命周期,提供事件傳播機制,支持模版渲染過程。 ? scopes層級 ng-controller指令使用scope.$new()方法創建新的scope。angularjs有個根作用域$rootScope(所有其他作用域的父親),新建應用時就有rootScope。 ng-controller指令是scope創建指令的例子。AngularJS碰到dom樹中scope創建指令時就會創建scope類的一個新的實例。(ng-repeat可以生成多個scope實例)新創建的scope使用parent屬性指向其父親。 ? scope層級和繼承 一個scope上定義的屬性可以對所有子scope可見,只是子scope 不能使用相同的名字重定義這個屬性。 scope的繼承跟原型鏈繼承一樣。繼承中讀很容易理解,寫有點復雜。 如下代碼: 運行此代碼,name變量在整個應用中可見,即使它只在最高層scope中定義。 跟js原型繼承一樣,子類的值不會影響父類的值。如果要改變父域的值,有幾種方式: 1、使用$parent屬性 通過直接指向父scope解決問題,麻煩的是,使用ng-model指令表達式作用在整個DOM結構上,在其他<input>標簽上插入另一個scope-creating指令,$parent將會指向另一個完全不同的scope. 所以應該避免使用$parent屬性。 2、將屬性綁定到一個對象上,并不直接指向一個scope屬性。如下: 這個方法不會在DOM樹結構上假定任何屬性。避免直接綁定到scope的屬性上。綁定到對象屬性上是更好的方法。如ng-model="thing.name" ? scope層級關系和事件系統 層級上的scope可用來作為事件總線。AngularJS讓我們通過scope的層級關系傳播命名事件。事件可以從任意一個scope上發出,向上($emit)或者向下($broadcast)傳播。 ? AngularJS核心服務和指令使用這個事件總線標志應用狀態的重要變化。例如,當location(URL)變化時可以監聽$locationChangeSucess事件: 每個scope實例上的$on方法可以用來注冊scope-event處理函數。類似于DOM事件,可以在event對象上調用preventDefault()和stopPropagation()方法。stopPropagation()方法將會阻止事件冒泡到scopes層級上,僅可以通過($emit)來向上發送事件。 在整個AngularJS框架中,只有三個emit的事件($includeContentRequested,$includeContentLoaded,$viewContentLoaded),和幾個broadcast的事件($locationChangeStart,$loactionChangeSuccess,$routeUpdate,$routeChangeStart,$routeChangeSuccess,??$routeChangeError?,$destroy)。scope事件使用非常謹慎,在發出自定義事件之前需要評估其他選項(主要是雙向數據綁定)。 ? scope生命周期 scope提供了獨立的命名空間,避免變量名沖突。在層級上組織scopes有利于管理內存。當scopes中的一個scope不需要了,可以destroy。因此,這個scope上的model和functionality也會被垃圾回收。可以通過scope-creating指令創建新的scope,可以通過調用$new()和$destroy()方法手動創建和銷毀scope. ? View 聲明式模板視圖 AngularJS提倡聲明式方法構建UI,即模版集中于描述想要的效果而不是如何實現。舉例如下: 需要創建一個表單,用戶輸入一段message并發送。message的長短限制在100個字符,如果長度超出,Send button將會disable。用戶需要知道還可以輸入多少字符。如果剩下的字符小于10,顯示字符數的style將會變化來提醒用戶。如下所示: 初步實現如下所示: 加上顯示的剩余字符數: 其次,如果message不符合長度限制,需要使Send按鈕失效。 當僅有幾個字符剩下時需要改變樣式: ? 聲明式指令表達想要的結果,避免操作DOM元素。 ? 模塊和依賴注入 模塊化 如何將全局定義的controller簡化為module。 使用modules變為: ? module像是angularjs已組織的對象(controllers,services等)的容器。為了定義一個module,需要提供第一個參數name。第二個參數來表示依賴的其他模塊。 調用angular.module函數返回一個新創建的module實例,進入這個實例,可以定義controllers。controller函數有以下參數: ? ? ?Controller名稱 ? ? ?Controller構造函數 通過ng-app屬性告知AngularJS?module的存在 協作對象 module不僅可以用來注冊angularjs框架直接調用的對象如controllers、filters等,也可以是任何應用開發人員定義的對象。還可以描述這些對象之間的依賴關系。 ? 注入依賴 scope對象可以注入到控制器實例中。AngularJS可以找出一個controller需要的新的scope實例,并能創建一個新的scope實例將scope實例注入到controller中。 angularjs的注入依賴執行以下功能: 理解需要用對象表示collaborator 找到需要的collaborator 將對象包裝成全功能的應用 注冊服務 AngularJS只能連接它知道的對象。第一步注入依賴注入的機制:注冊一個module對象,不是直接注冊對象實例,而是拋出對象創建方法給AngularJS的依賴注入系統。其次AngularJS解釋這些方法將對象實例化后再連接它們。最后連接的對象集合組成了可運行的應用。 在AngularJS中,有一個特定的$provide服務可以注冊不同的方法來創建對象。注冊的方法然后由$injector翻譯來提供可以使用的對象實例(有所有的依賴resolved和injected) $injector服務創建的對象指向了服務,在應用生命周期中,AngularJS將解釋給定的方法僅一次,所以僅能創建單個對象實例。 被$injector服務創建的對象即是服務。angularjs僅僅解釋給定的方法一次,所以僅僅會創建對象的一個單例。services是單例對象。 AngularJS僅僅是對象實例的集合,我們可以控制這些對象如何創建。 Services 不能注冊NotificationsService服務為一個value對象,因為需要與存檔服務表達依賴關系。依賴其他對象,為一個對象注冊方法的最簡單的方式是注冊一個結構化函數??墒褂靡韵聅ervice方法: NotificationsService結構化函數可以寫成如下: 通過使用AngularJS依賴注入,可以從NoificiationsService構造函數中消除新的關鍵字。這個服務與依賴的實例無關,可接受任何存檔服務。應用更靈活! 實際上service方法不常使用,但對于注冊預先存在的構造函數還是很方便的,這樣AngularJS可以管理由這些構造函數創建的對象。 ? Factories 是另一種創建對象的注冊方法,比service更加靈活,因為可以注冊任何抽象的對象創建函數,如下: AngularJS將使用提供的factory函數注冊一個返回對象??梢允侨我庥行У腏S對象,包括function對象。 factory方法是將對象放入AngularJS依賴注入系統的最常用方法。 ? Constants constants可以在模塊級別上定義并作為其他協作對象注入。 Constants對于創建services很有用,可以在多個不同應用中重用。有一個缺點是只要一個service依賴于一個constant,這個constant值必須提供。所以有時需要有默認的配置值并允許用戶根據需要修改比較好。 ? Providers 所有注冊方法只是Provider的特例。注冊notificationsService服務為一個provider的例子如下: 首先provider是一個函數,返回包含$get屬性的對象。$get屬性是一個factory函數,返回一個service實例??梢詫roviders視為對象,將factory函數嵌入到$get屬性中。 其次,從provider函數返回的對象有額外的方法和屬性。所以在$get方法觸發前可能設置配置選項,也可以設置maxLen屬性??赡苡懈鼜碗s的配置邏輯,因為服務還可以暴露配置方法。 ? 模塊的生命周期 為了支持providers,AngularJS將模塊的生命周期分為兩個階段: 配置階段:收集并配置所有方法 運行階段:執行任何后期實例化邏輯 ? 配置階段 providers僅僅在配置階段配置。providers可配置如下: 依賴有Provider后綴的notificationsServiceProvider對象表示方法準備執行。配置階段可以對對象創建方法做最后調整。 ? 執行階段 執行階段可以注冊任何需要在application bootstrap上執行的功能,可以將運行階段視為其他程序中主要方法。AngularJS模塊最大的區別是有多個配置和運行塊,不止一個入口。 如下: 模板: 不同階段不同注冊方法,總結下創建對象的不同方法以及這些方法對應的module的生命周期: ? 模塊依賴 AngularJS不僅可以管理對象依賴,也可以管理模塊間的依賴關系??梢院苋菀椎膶⑾嚓Pservices組成一個module,創建service庫。 例如,可以將notifications和archiving services移動到他們自己的modules中,如下: 這種方式每個service(或者相關services的集合)可以組合成一個可復用的實體(a module)。最高級別的模塊可以聲明所有模塊的依賴關系。 ? AngularJS模塊可以相互依賴,每個模塊有幾個services,但是各自的services可以依賴其他的services。這會引發幾個有趣的問題: 一個AngularJS模塊上定義的service依賴于另一個模塊的services? 子模塊中定義的service可以依賴父模塊的service或者其他子模塊中定義的services? 可以僅對特定module中可見的私有模塊services嗎? 在不同模塊中可以有同樣名字的services嗎? ? Services和模塊間的可見性 car服務定義在app模塊中。app模塊聲明了對engines模塊的依賴,dieselEngine服務定義在這個模塊上。car可以被engine的一個實例注入。 定義在相鄰模塊上的services相互之間都可見??梢詫ar服務移到單獨的模塊,然后改變模塊依賴,依賴engines和cars模塊的應用如下: 在之前的例子中,engine仍然可以注入到car中。 定義在應用中的modules中的service可以對其他所有模塊可見。 因為AngularJS結合所有模塊中的所有服務成一個大的應用層級的services,僅有一個給定名字的service。這點可以在依賴一個模塊但又想覆蓋模塊中的某些services情況下使用??梢灾苯釉赾ars模塊中重定義dieselEngine service如下: ? 當前AngularJS版本中,在一個模塊上定義的所有services對所有其他模塊都可見,無法限制一個模塊或者模塊子集上的服務的可見性。 ? 初寫文章,譯的不合適的地方,還望大牛們不吝賜教!!! 英文原文:Mastering Web Application Development with AngularJS
雙向數據綁定 不需要刷新模板,不需要使用框架API來更新模型,AngularJS可以智能檢測模型變化且相應的更新DOM,任何視圖的變化都會立刻反應到模型中,任何模型的變化也會反應到模版上。 ? AngularJS中的MVC模式 Scope scope對象是提供模型給視圖(模板)。通過將屬性賦值給scope的實例,可以生成新值來渲染模板。對于給定視圖,scope能夠用數據和特定的功能來擴充??梢酝ㄟ^在scope實例上定義功能提供具體的UI邏輯給模板。 例如可以為name變量創建一個getter函數: 可以在模版中使用函數: scope使我們能夠精確控制domain模型的哪部分、哪些操作對視圖層可用。 ? Controller 主要職責是初始化scope對象。具體包括: 提供初始模型值 通過UI交互(函數)來擴充scope controller是正常的js功能函數。沒有擴展任何具體框架類,不調用任何特定的AngularJS的api來執行操作,也不操作html模板和dom。 ? Model 僅是js的對象,不繼承任何框架基類,不以任何特別方式構建模型對象。為了提供模型給AngularJS,僅需要將模型賦值給scope。 ? 深入理解scope 每個$scope是Scope類的實例,Scope類有方法控制scope生命周期,提供事件傳播機制,支持模版渲染過程。 ? scopes層級 ng-controller指令使用scope.$new()方法創建新的scope。angularjs有個根作用域$rootScope(所有其他作用域的父親),新建應用時就有rootScope。 ng-controller指令是scope創建指令的例子。AngularJS碰到dom樹中scope創建指令時就會創建scope類的一個新的實例。(ng-repeat可以生成多個scope實例)新創建的scope使用parent屬性指向其父親。 ? scope層級和繼承 一個scope上定義的屬性可以對所有子scope可見,只是子scope 不能使用相同的名字重定義這個屬性。 scope的繼承跟原型鏈繼承一樣。繼承中讀很容易理解,寫有點復雜。 如下代碼: 運行此代碼,name變量在整個應用中可見,即使它只在最高層scope中定義。 跟js原型繼承一樣,子類的值不會影響父類的值。如果要改變父域的值,有幾種方式: 1、使用$parent屬性 通過直接指向父scope解決問題,麻煩的是,使用ng-model指令表達式作用在整個DOM結構上,在其他<input>標簽上插入另一個scope-creating指令,$parent將會指向另一個完全不同的scope. 所以應該避免使用$parent屬性。 2、將屬性綁定到一個對象上,并不直接指向一個scope屬性。如下: 這個方法不會在DOM樹結構上假定任何屬性。避免直接綁定到scope的屬性上。綁定到對象屬性上是更好的方法。如ng-model="thing.name" ? scope層級關系和事件系統 層級上的scope可用來作為事件總線。AngularJS讓我們通過scope的層級關系傳播命名事件。事件可以從任意一個scope上發出,向上($emit)或者向下($broadcast)傳播。 ? AngularJS核心服務和指令使用這個事件總線標志應用狀態的重要變化。例如,當location(URL)變化時可以監聽$locationChangeSucess事件: 每個scope實例上的$on方法可以用來注冊scope-event處理函數。類似于DOM事件,可以在event對象上調用preventDefault()和stopPropagation()方法。stopPropagation()方法將會阻止事件冒泡到scopes層級上,僅可以通過($emit)來向上發送事件。 在整個AngularJS框架中,只有三個emit的事件($includeContentRequested,$includeContentLoaded,$viewContentLoaded),和幾個broadcast的事件($locationChangeStart,$loactionChangeSuccess,$routeUpdate,$routeChangeStart,$routeChangeSuccess,??$routeChangeError?,$destroy)。scope事件使用非常謹慎,在發出自定義事件之前需要評估其他選項(主要是雙向數據綁定)。 ? scope生命周期 scope提供了獨立的命名空間,避免變量名沖突。在層級上組織scopes有利于管理內存。當scopes中的一個scope不需要了,可以destroy。因此,這個scope上的model和functionality也會被垃圾回收。可以通過scope-creating指令創建新的scope,可以通過調用$new()和$destroy()方法手動創建和銷毀scope. ? View 聲明式模板視圖 AngularJS提倡聲明式方法構建UI,即模版集中于描述想要的效果而不是如何實現。舉例如下: 需要創建一個表單,用戶輸入一段message并發送。message的長短限制在100個字符,如果長度超出,Send button將會disable。用戶需要知道還可以輸入多少字符。如果剩下的字符小于10,顯示字符數的style將會變化來提醒用戶。如下所示: 初步實現如下所示: 加上顯示的剩余字符數: 其次,如果message不符合長度限制,需要使Send按鈕失效。 當僅有幾個字符剩下時需要改變樣式: ? 聲明式指令表達想要的結果,避免操作DOM元素。 ? 模塊和依賴注入 模塊化 如何將全局定義的controller簡化為module。 使用modules變為: ? module像是angularjs已組織的對象(controllers,services等)的容器。為了定義一個module,需要提供第一個參數name。第二個參數來表示依賴的其他模塊。 調用angular.module函數返回一個新創建的module實例,進入這個實例,可以定義controllers。controller函數有以下參數: ? ? ?Controller名稱 ? ? ?Controller構造函數 通過ng-app屬性告知AngularJS?module的存在 協作對象 module不僅可以用來注冊angularjs框架直接調用的對象如controllers、filters等,也可以是任何應用開發人員定義的對象。還可以描述這些對象之間的依賴關系。 ? 注入依賴 scope對象可以注入到控制器實例中。AngularJS可以找出一個controller需要的新的scope實例,并能創建一個新的scope實例將scope實例注入到controller中。 angularjs的注入依賴執行以下功能: 理解需要用對象表示collaborator 找到需要的collaborator 將對象包裝成全功能的應用 注冊服務 AngularJS只能連接它知道的對象。第一步注入依賴注入的機制:注冊一個module對象,不是直接注冊對象實例,而是拋出對象創建方法給AngularJS的依賴注入系統。其次AngularJS解釋這些方法將對象實例化后再連接它們。最后連接的對象集合組成了可運行的應用。 在AngularJS中,有一個特定的$provide服務可以注冊不同的方法來創建對象。注冊的方法然后由$injector翻譯來提供可以使用的對象實例(有所有的依賴resolved和injected) $injector服務創建的對象指向了服務,在應用生命周期中,AngularJS將解釋給定的方法僅一次,所以僅能創建單個對象實例。 被$injector服務創建的對象即是服務。angularjs僅僅解釋給定的方法一次,所以僅僅會創建對象的一個單例。services是單例對象。 AngularJS僅僅是對象實例的集合,我們可以控制這些對象如何創建。 Services 不能注冊NotificationsService服務為一個value對象,因為需要與存檔服務表達依賴關系。依賴其他對象,為一個對象注冊方法的最簡單的方式是注冊一個結構化函數??墒褂靡韵聅ervice方法: NotificationsService結構化函數可以寫成如下: 通過使用AngularJS依賴注入,可以從NoificiationsService構造函數中消除新的關鍵字。這個服務與依賴的實例無關,可接受任何存檔服務。應用更靈活! 實際上service方法不常使用,但對于注冊預先存在的構造函數還是很方便的,這樣AngularJS可以管理由這些構造函數創建的對象。 ? Factories 是另一種創建對象的注冊方法,比service更加靈活,因為可以注冊任何抽象的對象創建函數,如下: AngularJS將使用提供的factory函數注冊一個返回對象??梢允侨我庥行У腏S對象,包括function對象。 factory方法是將對象放入AngularJS依賴注入系統的最常用方法。 ? Constants constants可以在模塊級別上定義并作為其他協作對象注入。 Constants對于創建services很有用,可以在多個不同應用中重用。有一個缺點是只要一個service依賴于一個constant,這個constant值必須提供。所以有時需要有默認的配置值并允許用戶根據需要修改比較好。 ? Providers 所有注冊方法只是Provider的特例。注冊notificationsService服務為一個provider的例子如下: 首先provider是一個函數,返回包含$get屬性的對象。$get屬性是一個factory函數,返回一個service實例??梢詫roviders視為對象,將factory函數嵌入到$get屬性中。 其次,從provider函數返回的對象有額外的方法和屬性。所以在$get方法觸發前可能設置配置選項,也可以設置maxLen屬性??赡苡懈鼜碗s的配置邏輯,因為服務還可以暴露配置方法。 ? 模塊的生命周期 為了支持providers,AngularJS將模塊的生命周期分為兩個階段: 配置階段:收集并配置所有方法 運行階段:執行任何后期實例化邏輯 ? 配置階段 providers僅僅在配置階段配置。providers可配置如下: 依賴有Provider后綴的notificationsServiceProvider對象表示方法準備執行。配置階段可以對對象創建方法做最后調整。 ? 執行階段 執行階段可以注冊任何需要在application bootstrap上執行的功能,可以將運行階段視為其他程序中主要方法。AngularJS模塊最大的區別是有多個配置和運行塊,不止一個入口。 如下: 模板: 不同階段不同注冊方法,總結下創建對象的不同方法以及這些方法對應的module的生命周期: ? 模塊依賴 AngularJS不僅可以管理對象依賴,也可以管理模塊間的依賴關系??梢院苋菀椎膶⑾嚓Pservices組成一個module,創建service庫。 例如,可以將notifications和archiving services移動到他們自己的modules中,如下: 這種方式每個service(或者相關services的集合)可以組合成一個可復用的實體(a module)。最高級別的模塊可以聲明所有模塊的依賴關系。 ? AngularJS模塊可以相互依賴,每個模塊有幾個services,但是各自的services可以依賴其他的services。這會引發幾個有趣的問題: 一個AngularJS模塊上定義的service依賴于另一個模塊的services? 子模塊中定義的service可以依賴父模塊的service或者其他子模塊中定義的services? 可以僅對特定module中可見的私有模塊services嗎? 在不同模塊中可以有同樣名字的services嗎? ? Services和模塊間的可見性 car服務定義在app模塊中。app模塊聲明了對engines模塊的依賴,dieselEngine服務定義在這個模塊上。car可以被engine的一個實例注入。 定義在相鄰模塊上的services相互之間都可見??梢詫ar服務移到單獨的模塊,然后改變模塊依賴,依賴engines和cars模塊的應用如下: 在之前的例子中,engine仍然可以注入到car中。 定義在應用中的modules中的service可以對其他所有模塊可見。 因為AngularJS結合所有模塊中的所有服務成一個大的應用層級的services,僅有一個給定名字的service。這點可以在依賴一個模塊但又想覆蓋模塊中的某些services情況下使用??梢灾苯釉赾ars模塊中重定義dieselEngine service如下: ? 當前AngularJS版本中,在一個模塊上定義的所有services對所有其他模塊都可見,無法限制一個模塊或者模塊子集上的服務的可見性。 ? 初寫文章,譯的不合適的地方,還望大牛們不吝賜教!!! 英文原文:Mastering Web Application Development with AngularJS
轉載于:https://www.cnblogs.com/wwjuan/p/5015242.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的AngularJS之禅的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Thinking in Java,Fou
- 下一篇: 导航选中后标记的样式实现滑动效果