初識angular架構後的所思所想,angular所思

來源:互聯網
上載者:User

初識angular架構後的所思所想,angular所思

因為工作中實際開發需要,才開始接觸angular架構。從當初的比葫蘆畫瓢,被各種問題、概念折磨摧殘,到現在有一定的瞭解認識,覺得有必要將自己的認識進行簡單的總結。不到位的地方還望多多包涵。

 1.雙向資料繫結
      目前業內盛行各種MV**架構,相關的架構不斷湧現,而angular就是其中的一種(MVVM)。MV**架構其實最核心的問題就是將view層和model分離開來,降低代碼的耦合性,做到資料和表現的分離,MVC、MVP、MVVM均有相同的目標,而他們之間的不同就在於如何把model層和view關聯起來。

      資料在model、view層如何流動就成了問題的關鍵,angular通過dirty-check實現了資料的雙向繫結。所謂的雙向繫結,就是view的變化可以反映到model層,而model資料的變化可以在view體現出來。那麼angular是如何做到雙向繫結的?為何成為dirty-check呢?還是前端的一個原始問題出發吧:

 html:

 <input type="button" value="increase 1" id="J-increase" /> <span id="J-count"></span>

js:

 <script> var bindDate = {  count: 1,  appy: function () {   document.querySelector('#J-count').innerHTML = this.count;  },  increase: function () {   var _this = this;   document.querySelector('#J-increase').addEventListener('click', function () {    _this.count++;    appy();   }, true);  },  initialize: function () {    // 初始化   this.appy();    //   this.increase();   }  };  bindDate.initialize(); </script>

在上面的例子中,存在兩個過程:

view層影響model層: 頁面上點擊button,造成資料count的數量增加1
model層反應view層: count發生完變化以後,通過apply函數來反映到view層上
這是以前使用jquery、YUI等類庫實現的資料處理,這裡面存在的問題很明顯:

  • 涉及到了大量的DOM操作;
  •  過程繁瑣;
  • 代碼耦合性太高,不便於寫單元測試。

下面來看看angular是如何進行資料處理的:

第一步. 添加watcher:就是當資料發生變化的時候,需要檢測哪些對象,需要先進行註冊

// 對angular裡面的源碼進行了精簡  $watch: function(watchExp, listener, objectEquality) {  var scope = this,   array = scope.$$watchers,  watcher = {    fn: listener,    last: initWatchVal,   get: get,   exp: watchExp,    eq: !!objectEquality  };  if (!array) {   array = scope.$$watchers = []; }  array.unshift(watcher); }

第二步. dirty-check:就是當有某個scope範圍下的資料發生變化後,需要遍曆檢測註冊的$$watchers = [...]

 $digest: function() { while (length--) {   watch = watchers[length];  watch.fn(value, lastValue, scope); } }

這樣就實現了資料的雙向繫結,上面的實現是否跟自訂事件很像呢?可以看到使用了觀察者設計模式或(publisher-subscriber)。

 2.依賴注入
     使用過spring架構的同學都知道,Ioc、AOP是spring裡面最重要的兩個概念,而Ioc就可以裡面為注入依賴(DI),很明顯angular帶有非常濃厚的後端色彩。

     同樣,首先來看下不使用DI,是如何解決對象相互依賴的:

 function Car() { ...} Car.prototype = { run: function () {...}} function Benz() { var cat = new Car(); }Benz.prototype = {  ...}

      在上面的例子中,類Benz依賴於類Car,直接通過內部New來解決這種依賴關係。這樣做的弊端非常明顯,代碼耦合性變高,不利於維護。後端架構很早就意識到了這個問題,spring早期通過在xml檔案中註冊對象之間的依賴關係,後來有通過anotation的方式更加方便地解決DI問題,COS端的同學可以看看後端的代碼。

js語言本身是不具有註解(annotation)機制的,那angular是如何?的呢?

1.類比註解

 // 註解的類比 function annotate(fn, strictDi, name) { var $inject; if (!($inject = fn.$inject)) {  $inject = [];  $inject.push(name); }else if (isArray(fn)) {  $inject = fn.slice(0, last); }  return $inject; } createInjector.$$annotate = annotate;

2. 注入對象的建立

 function createInjector(modulesToLoad, strictDi) {  //通過singleton模式建立對象  var providerCache = {    $provide: {      provider: supportObject(provider),      factory: supportObject(factory),      service: supportObject(service),      value: supportObject(value),      constant: supportObject(constant),     decorator: decorator   }   },  instanceCache = {},  instanceInjector = (instanceCache.$injector =  createInternalInjector(instanceCache, function(serviceName, caller) {  var provider = providerInjector.get(serviceName + providerSuffix, caller);     return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);    })); return instanceInjector; }

3. 擷取注入對象

 

function invoke(fn, self, locals, serviceName) { var args = [],  $inject = annotate(fn, strictDi, serviceName); for (...) {  key = $inject[i];   // 替換成依賴的對象   args.push(   locals && locals.hasOwnProperty(key)     ? locals[key]    : getService(key, serviceName)   ); }  if (isArray(fn)) {  fn = fn[length];  }     return fn.apply(self, args);}

       到這裡,是否是看到很多後端架構設計的思路,沒有anotation就類比一個,難怪PPK要說angular是" a front-end framework by non-front-enders for non-front-enders"

3.controller通訊
    在實際開發中,應用系統會非常龐大,一個應用app不可能只存在一個controller,那麼不同controller之間就存在通訊的可能,如何解決這個常見問題,主要有兩種方法:

1.事件機制: 把事件註冊在$rootScope上,這樣做的問題就是會在$rootScope上註冊太大事件,會引起一些列後續問題

 //controller1app.controller('controller1', function ($rootScope) { $rootScope.$on('eventType', function (arg) {    ......  }) })// controller2app.controller('controller2', function ($rootScope) {   $rootScope.$emit('eventType',arg); or  $rootScope.$broadcast('eventType',arg); })

 2.通過service: 充分利用angular的DI特性,利用service是單例的特點,在不同controller之間起到橋樑作用

// 註冊serviceapp.service('Message', function () { return {  count: void(0); } }) // controller1,修改service的count值app.controller('controller1', function ($scope, Message) {  $scope.count = 1; Message.count = $scope.count;}); // controller2, 擷取service的count值app.controller('controller2', function ($scope, Message) {$scope.num = Message.count; });

4.service的特點

1. 單例(singleton): angular裡面只有service才可以進行DI諸如,controller、directive這些均不具有這些功能,service字面上就是提供一些基本的服務,跟具體的業務沒有關聯,而controller、directive則與具體業務緊密相關聯,所以需要保證service的唯一性。

 2. lazy new:angular首先會產生service的provider,但是並沒有立即產生對應的service,只有到需要這些服務的時候才會進行執行個體化操作。

3. provider)的分類: provider()、factory、service、value、constant,其中provider是最底層的實現,其他方式都是在其基礎上的文法糖(sugar),需要注意的是這些服務最終均要添加$get方法,因為具體service是通過執行$get方法產生的。 

5. directive的實現
     directive的編譯(compiler)包括兩個階段: compile、link。簡單來講compile階段主要處理template DOM,此時並不涉及範圍問題,也就是沒有進行資料渲染,例如ngRepeate指令就是通過compile進行template修改的,執行compile後會返回link函數,覆蓋後面定義的link函數;而link主要是進行資料渲染,分為pre-link和post-link兩個環節,這兩個環節解析的順序是相反,post-link是先解析內部,然後才是外部,這樣對directive的解析就是安全的,因為directive內部還可以包括directive,同時link是對真正DOM的處理,會涉及DOM操作的效能問題。

本文涉及的內容還不是很全民,之後還會有相應補充,希望大家也可以對angular架構進行學習探討。

您可能感興趣的文章:
  • 教你用AngularJS架構一行JS代碼實現控制項驗證效果
  • AngularJS入門知識之MVW類架構的編程思想探討
  • 淺析webapp架構AngularUI的demo
  • webapp架構AngularUI的demo改造之路
  • 分享使用AngularJS建立應用的5個架構
  • 深入探究AngularJS架構中Scope對象的超級教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.