前言 :

寫東西一定要有前言的 XD 上課心得也是一樣

我這次上的課叫做 "《台北》AngularJS 開發實戰:新手入門篇" 老師是 will 保哥

http://miniasp.kktix.cc/events/dct-104013

一直以來都是自學 AngularJS,所以有些簡單的 code 寫得出來但是不知道背後原理到底是什麼

所以應用上覺得超困難的,綁手綁腳...看別人的 code 覺得超簡單超簡潔,但是換了自己就寫不出來 冏

而且jQuery 用習慣了實在很難轉到 AngularJS,因此昨天去上了保哥的課覺得獲益良多

課堂上很多人是從 jQuery 跳到 AngularJs 遇到轉換上困難,原因就是因為大家都不了解背後原理的關係

因為jQuery 是直覺操作DOM的思維,所以是屬於直覺式的思考,而 AngularJS 是一個框架,凡事必須要從 model 來思考

當思考模式轉不過來就會發生 1. 寫不出來 2. 寫出來的東西很可怕的情況

所以下面這些是這次上課所學到的有些觀念 + 背後運作原理的部分,跟程式碼比較沒關係

一樣有目錄 :

1. 為何在 angularjs 不能使用 value 直接給值?

2. AngularJS 都要出2.0了而且是大改,還有必要學習 1.X 版嗎?

3. 哪些專案適合使用 AngularJS 來開發

3.1. 那目前傳統的 ASP.Net Web Form 適合使用 AngularJS 來開發嗎?

4. 避免 AngularJs 1.X 的 dirty-checking (頻繁檢查) 引發的效能問題

5. AngulraJs 1.3 以上 Controller 的新寫法與改善的問題

6. Scope 作用域的概念

7. 課後 AngularJs 的開發思維整理

 

1. 為何在 angularjs 不能使用 value 直接給值? 

<input type="text" ng-model="msg" value="hello word!" />

設定了 value="hello word!" 之後會長下面這樣,value 形同虛設

擷取  

解答 : 

在 angularjs 的世界所有的值都會去 model 裡面找,當頁面一載入就會去掃所有View中的 ng-model

並且去背後的 model 中找相對應的值,但是因為 model 中沒有名字為 msg 的值

所以本來呈現的 value 值就等同於被蓋掉成空值了

angularjs

但其實檢視最後的 HTML 原始檔,原本value 其實是還在的,如下圖的 HTML 原始碼 :

擷取   

只是因為 input 下了 ng-model 所以被 AngularJS 控制,而 AngularJs 的值都是存放在 model 的關係 

這時只要在輸入框輸入資料,AngularJS就會自動在 model 中建立一個 msg 了

所以才能直接用表達式輸出 model 中 msg 的值,如下圖 :

擷取  

如果要給 ng-model 初始值可以使用 ng-init 

ex : <input type="text" ng-model="msg" ng-init="msg='test'" />

使用了 ng-init 就會在 model 中建立初始值了

如下圖 :  

但其實也不建議初始值寫在 ng-init 裡面,有關初始值的控管比較建議寫在 controller 中,view 只要單純顯示畫面就好了

寫在 controller 中如下,雖然這個 controller 是不好的寫法,原因等下會解釋

擷取   

 

2. AngularJS 都要出2.0了而且是大改,還有必要學習 1.X 版嗎? 

解答 : 

其實我要來上這堂課之前也抱持著這個問題,這就像買了 Sony Z4,結果半年後 Z5 要出來的感覺一樣

感覺不好就算了,重點是怕被淘汰或不支援,既然提到版本,上課時就有順便提了一下 2.0 的優勢

AngularJS 2.0 大幅改善了 1.X 的缺點 dirty-checking (頻繁檢查) 帶來的效能很差的問題

保哥分享一個驚為天人的影片,影片是一個 table 中的所有 td,同時被 angularjs 操作 DOM 的影片

  

可以看到 2.0 已經沒有 1.X 致命的問題了

AngularJS 2.0 新的特性有這些 : http://ww.daliulian.org/cat15/node290749

但是架構可以說是大改變,幾乎可以說是重新學習一套新語言了,那有沒有必要繼續學 1.X 版咧?

目前 1.X 大概還會支援個 3 ~ 5年,而且目前網路上有成群的 AngularJS 1.X 套件

很多套件 : http://ngmodules.org/

短時間內也不太可能會完全被淘汰,而且目前 AngularJS 還是一套非常好用的框架,所以還是值得學習

很值得運用在適合的專案上 (等下會提到何謂適合)


update : 2.0 已經確定會向下支援 1.x了,所以不用擔心這個問題

 

3. 哪些專案適合使用 AngularJS 來開發

解答 : 

AngularJS 雖然是一個很好的框架,但是在操作 DOM 上非常的弱而且有效能上的問題

所以如果你的專案是需要頻繁操作 DOM 做一些特效的還是使用 jQuery 吧

AngularJs 很適合用來開發 SPA (Single Page Application)

在使用 AngularJs 開發專案的時候一般來說是不換頁的,而且也不會使用 AngularJS 做分頁 (正常)

會使用 AJAX 與 Server 溝通,靠傳遞 JSON 到前端來做 CRUD

於是我就有問了下面這個問題.....

 

3.1. 那目前傳統的 ASP.Net Web Form 適合使用 AngularJS 來開發嗎?

我的疑問是....

因為傳統的 Web Form 會需要 Postback來傳值,而且 Web Form 多少還是會用到 Server Control 

很多事件的處理都是寫在 Server 端,而且 Postback 之後重新載入頁面 js 就不見了

解答如下 :

如果是傳統的 .Net Web Form 幾乎不可能使用 AngularJS 做開發,就用Web Form 本身的控制項就好了

但是 ASP.Net MVC 就非常適合,因為 .Net MVC 預設就是不換頁的,非常適合使用 AngularJS

而且 ASP.Net MVC 預設就是支援 JSON 的,所以更適合使用 AngularJS 

結論就是...趕快去學 ASP.Net MVC 吧

 

4. 避免 AngularJs 1.X 的 dirty-checking (頻繁檢查) 引發的效能問題

這問題可以用來順便了解一下 AngulaJs 這個框架的運作,由於 AngularJS 有 two way binding 的特性

當你一異動到任何一個 model 就會重新掃一次頁面,因為他要確保頁面上與 model 有關的值都是最新的

大概就是下圖的意思 (抱歉畫得很爛),可以想像 Model 在 View 的背後 (只是我畫不出來)

angularjs     

只要一改變 model 中的任一值就會重新掃一次頁面,如果掃的過程中發現又被異動了....就會再掃一次!

所以容易造成無窮迴圈啊,所以官方有做了一個限制,如果掃了超過 10 次的話就會強制停止迴圈  

這個步驟雖然確保了頁面上與 model 有關的值都是最新的,但是想也知道非常的浪費效能啊!

AngularJs 2.0 有改善了這個問題,但我們還在 1.X 只能在設計上多注意

或是使用 controller as 可以減少一些效能消耗 (等下會提到)

以下這個網址還蠻不錯可以參考一下作法 : 為什麼我們的 Angular 應用總是很慢

 

5. AngulraJs 1.3 以上 Controller 的新寫法與改善的問題

這一點其實不是要注重在 code,而是可以順便了解到為什麼這樣寫可以改善效能

了解之後會對個框架的運作更為了解,包含他目前所遭遇到的問題

但其實我一直是使用新的寫法,只是我根本不知道差在哪...與為何要這樣寫 = =

要比較前首先要來複習一下 1.3 之前的寫法

<body ng-app>
<div ng-controller="mycontroller">
<input type="text" ng-model="msg" />
<p>{{ msg }}</p>
</div>
</body>
<script>
function mycontroller ($scope) {
$scope.msg = "test";
}
</script>

只要在 js 寫個 function 傳入一個 $scope 就可以完成一個 controller

傳入的 $scope 就代表了 model,對 model 做修改就會導致 AngularJs 將頁面整個重新掃一遍

所以 $scope.msg = "test"; 這個動作就會去掃頁面中所有有用到 msg 的地方,並將它的值同步

 

1.3 以後的寫法強制改為以下這樣,建立 controller 時要先建立 module

<body ng-app="myapp">
<div ng-controller="mycontroller">
<input type="text" ng-model="msg" />
<p>{{ msg }}</p>
</div>
</body>
<script>
angular.module("myapp",[])
.controller("mycontroller",["$scope","$log", function($scope, $log) {
$scope.msg = "test";
}]);
</script>

 

但最好的寫法是這樣,使用 controller as 的語法

<body ng-app="myapp">
<div ng-controller="mycontroller as ctrl">
<input type="text" ng-model="ctrl.msg" />
<p>{{ ctrl.msg }}</p>
</div>
</body>
<script>
angular.module("myapp",[])
.controller("mycontroller",["$scope","$log", mycontroller]);

function mycontroller ($scope, $log) {
var vm = this;
vm.msg = "test";
}
</script>

 

其中 controller 裡面的那個 this 就代表了 "controller as" 區塊間的 view model

意思就是以後 model 有變更就不受 $scope 的影響,就只會掃 controller as 的範圍區塊

因為不用掃整個 $scope 效能也會更好

可以參考一下保哥的這篇

http://blog.miniasp.com/post/2013/07/23/AngularJS-five-ways-to-register-ngController.aspx

ps 小插曲 :

上面的範例之所以注入 $log 服務是因為上課時有人問到如何寫 log

一般來說是使用 console.log() 但這是瀏覽器提供的功能,如果要做單元測試的話碰到 console.log() 就死在那邊了

所以官方建議改用 $log 服務來寫 log

 

6. Scope 作用域的概念

scope 是用來偵測 model 物件的改變,scope 也有物件繼承的特性

有些 directives 使用後也會產生自己的 scope,ex : ng-controller、ng-repeat...等

假設有以下這種狀況,有兩個同樣名字的 controller 區塊

<div ng-controller="controllerA">
</div>
<div ng-controller="controllerA">
</div>

 

 一個 controller 就會產生一個 scope,所以雖然都是 controllerA,但是這是兩個不同的 scope

用一張小畫家畫的爛圖來表示就是這樣

未命名   

兩個各自的 scope,再加上最外層有一個 $rootScope

那如果是像下面這樣的話 :

<div ng-controller="controllerA">
<div ng-controller="controllerB">
</div>
</div>

 如下面小畫家畫的爛圖所表示,Scope 作用域會長這樣

未命名     

scope B 就會繼承到 scope A,所以可以使用 scope A的內容

而有些 directives 也會產生自己的 scope,像是 ng-repeat

所以就變成 scope B 裡面又有其他 scope 存在 (懶得畫圖了)

 

7. 課後 AngularJs 的開發思維整理

model 的思考對於 AngularJs 開發來說非常的重要,在開發的時候要優先考慮 model

然後 HTML 就當他是個樣板,所有的邏輯都不要寫在 HTML 之中要寫在 controller (關注點分離)

包含初始值的設定與事件都是寫在 controller,盡量避免用操作 DOM 的方式去思考 (ex:看到元素就想綁事件取ID)

要想成背後有一個 model,你只要改了 model,頁面上所有用到的值都會跟著改,所以不需要管 view,只要管 model

在開發時也要考慮 angularjs 的效能問題,減少更改 model 的機會就可以減少浪費效能的機會

 

以上是這堂課所學到的一些觀念

因為是初級班所以觀念非常重要,所以 code 的部分沒有講太多 = =

其他有機會可以上進階課程 (但是額滿了啊啊啊啊)

 

 

AngularJS 學習筆記系列 : (依本人的上進心持續增加)

AngularJS 初學者筆記與教學 (一) - 使用方式、Expression、Controller、Module

AngularJS 初學者筆記與教學 (二) 內建的簡單指令之1 ng-click、ng-show、ng-hide

AngularJS 初學者筆記與教學 (三) - AngularJS 的載入流程與 ng-cloak 運作原理 

AngularJS 初學者筆記與教學 (四) - 如何動態改變 CSS 樣式,使用 ng-class、ng-style

AngularJS 初學者筆記與教學 (五) - 繼續深入學習常用的 ng-repeat

AngularJS 初學者筆記與教學 (六) - 單元測試

AngularJS 初學者筆記與教學 (新手入門課程 - 課後心得篇)

AngularJS 初學者筆記與教學 (七) - FormController 的表單驗證與資料檢查

 

創作者介紹
創作者 小雕 的頭像
小雕

小雕雕的家

小雕 發表在 痞客邦 留言(0) 人氣()