欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

初識(shí)angular框架后的所思所想

 更新時(shí)間:2016年02月19日 09:36:51   投稿:lijiao  
這篇文章主要介紹了初識(shí)angular框架后的所思所想,學(xué)習(xí)認(rèn)識(shí)angular后的一些個(gè)人問(wèn)題總結(jié),需要的朋友可以參考下

因?yàn)楣ぷ髦袑?shí)際開(kāi)發(fā)需要,才開(kāi)始接觸angular框架。從當(dāng)初的比葫蘆畫(huà)瓢,被各種問(wèn)題、概念折磨摧殘,到現(xiàn)在有一定的了解認(rèn)識(shí),覺(jué)得有必要將自己的認(rèn)識(shí)進(jìn)行簡(jiǎn)單的總結(jié)。不到位的地方還望多多包涵。

 1.雙向數(shù)據(jù)綁定
      目前業(yè)內(nèi)盛行各種MV**框架,相關(guān)的框架不斷涌現(xiàn),而angular就是其中的一種(MVVM)。MV**框架其實(shí)最核心的問(wèn)題就是將view層和model分離開(kāi)來(lái),降低代碼的耦合性,做到數(shù)據(jù)和表現(xiàn)的分離,MVC、MVP、MVVM均有相同的目標(biāo),而他們之間的不同就在于如何把model層和view關(guān)聯(lián)起來(lái)。

      數(shù)據(jù)在model、view層如何流動(dòng)就成了問(wèn)題的關(guān)鍵,angular通過(guò)dirty-check實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定。所謂的雙向綁定,就是view的變化可以反映到model層,而model數(shù)據(jù)的變化可以在view體現(xiàn)出來(lái)。那么angular是如何做到雙向綁定的?為何成為dirty-check呢?還是前端的一個(gè)原始問(wèn)題出發(fā)吧:

 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>

在上面的例子中,存在兩個(gè)過(guò)程:

view層影響model層: 頁(yè)面上點(diǎn)擊button,造成數(shù)據(jù)count的數(shù)量增加1
model層反應(yīng)view層: count發(fā)生完變化以后,通過(guò)apply函數(shù)來(lái)反映到view層上
這是以前使用jquery、YUI等類(lèi)庫(kù)實(shí)現(xiàn)的數(shù)據(jù)處理,這里面存在的問(wèn)題很明顯:

  • 涉及到了大量的DOM操作;
  •  過(guò)程繁瑣;
  • 代碼耦合性太高,不便于寫(xiě)單元測(cè)試。

下面來(lái)看看angular是如何進(jìn)行數(shù)據(jù)處理的:

第一步. 添加watcher:就是當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候,需要檢測(cè)哪些對(duì)象,需要先進(jìn)行注冊(cè)

// 對(duì)angular里面的源碼進(jìn)行了精簡(jiǎn) 
 $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:就是當(dāng)有某個(gè)scope作用域下的數(shù)據(jù)發(fā)生變化后,需要遍歷檢測(cè)注冊(cè)的$$watchers = [...]

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

這樣就實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定,上面的實(shí)現(xiàn)是否跟自定義事件很像呢?可以看到使用了觀察者設(shè)計(jì)模式或(publisher-subscriber)。

 2.依賴(lài)注入
     使用過(guò)spring框架的同學(xué)都知道,Ioc、AOP是spring里面最重要的兩個(gè)概念,而Ioc就可以里面為注入依賴(lài)(DI),很明顯angular帶有非常濃厚的后端色彩。

     同樣,首先來(lái)看下不使用DI,是如何解決對(duì)象相互依賴(lài)的:

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


      在上面的例子中,類(lèi)Benz依賴(lài)于類(lèi)Car,直接通過(guò)內(nèi)部New來(lái)解決這種依賴(lài)關(guān)系。這樣做的弊端非常明顯,代碼耦合性變高,不利于維護(hù)。后端框架很早就意識(shí)到了這個(gè)問(wèn)題,spring早期通過(guò)在xml文件中注冊(cè)對(duì)象之間的依賴(lài)關(guān)系,后來(lái)有通過(guò)anotation的方式更加方便地解決DI問(wèn)題,COS端的同學(xué)可以看看后端的代碼。

js語(yǔ)言本身是不具有注解(annotation)機(jī)制的,那angular是如何實(shí)現(xiàn)的呢?

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. 注入對(duì)象的創(chuàng)建

 function createInjector(modulesToLoad, strictDi) {
  //通過(guò)singleton模式創(chuàng)建對(duì)象
  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. 獲取注入對(duì)象

 

function invoke(fn, self, locals, serviceName) {
 var args = [],
  $inject = annotate(fn, strictDi, serviceName);

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

       到這里,是否是看到很多后端框架設(shè)計(jì)的思路,沒(méi)有anotation就模擬一個(gè),難怪PPK要說(shuō)angular是" a front-end framework by non-front-enders for non-front-enders"

3.controller通信
    在實(shí)際開(kāi)發(fā)中,應(yīng)用系統(tǒng)會(huì)非常龐大,一個(gè)應(yīng)用app不可能只存在一個(gè)controller,那么不同controller之間就存在通信的可能,如何解決這個(gè)常見(jiàn)問(wèn)題,主要有兩種方法:

1.事件機(jī)制: 把事件注冊(cè)在$rootScope上,這樣做的問(wèn)題就是會(huì)在$rootScope上注冊(cè)太大事件,會(huì)引起一些列后續(xù)問(wèn)題

 //controller1
app.controller('controller1', function ($rootScope) {
 $rootScope.$on('eventType', function (arg) {
    ......
  })
 })

// controller2
app.controller('controller2', function ($rootScope) {
   $rootScope.$emit('eventType',arg);
 or
  $rootScope.$broadcast('eventType',arg);
 })

 2.通過(guò)service: 充分利用angular的DI特性,利用service是單例的特點(diǎn),在不同controller之間起到橋梁作用

// 注冊(cè)service
app.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的特點(diǎn)

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

 2. lazy new:angular首先會(huì)生成service的provider,但是并沒(méi)有立即生成對(duì)應(yīng)的service,只有到需要這些服務(wù)的時(shí)候才會(huì)進(jìn)行實(shí)例化操作。

3. provider)的分類(lèi): provider()、factory、service、value、constant,其中provider是最底層的實(shí)現(xiàn),其他方式都是在其基礎(chǔ)上的語(yǔ)法糖(sugar),需要注意的是這些服務(wù)最終均要添加$get方法,因?yàn)榫唧wservice是通過(guò)執(zhí)行$get方法生成的。 

5. directive的實(shí)現(xiàn)
     directive的編譯(compiler)包括兩個(gè)階段: compile、link。簡(jiǎn)單來(lái)講compile階段主要處理template DOM,此時(shí)并不涉及作用域問(wèn)題,也就是沒(méi)有進(jìn)行數(shù)據(jù)渲染,例如ngRepeate指令就是通過(guò)compile進(jìn)行template修改的,執(zhí)行compile后會(huì)返回link函數(shù),覆蓋后面定義的link函數(shù);而link主要是進(jìn)行數(shù)據(jù)渲染,分為pre-link和post-link兩個(gè)環(huán)節(jié),這兩個(gè)環(huán)節(jié)解析的順序是相反,post-link是先解析內(nèi)部,然后才是外部,這樣對(duì)directive的解析就是安全的,因?yàn)閐irective內(nèi)部還可以包括directive,同時(shí)link是對(duì)真正DOM的處理,會(huì)涉及DOM操作的性能問(wèn)題。

本文涉及的內(nèi)容還不是很全民,之后還會(huì)有相應(yīng)補(bǔ)充,希望大家也可以對(duì)angular框架進(jìn)行學(xué)習(xí)探討。

相關(guān)文章

  • AngularJS 過(guò)濾與排序詳解及實(shí)例代碼

    AngularJS 過(guò)濾與排序詳解及實(shí)例代碼

    這篇文章主要介紹了AngularJS 過(guò)濾與排序,這里整理了詳細(xì)的資料及簡(jiǎn)單實(shí)例代碼,有需要的小伙伴可以參考下
    2016-09-09
  • AngularJS實(shí)現(xiàn)與后臺(tái)服務(wù)器進(jìn)行交互的示例講解

    AngularJS實(shí)現(xiàn)與后臺(tái)服務(wù)器進(jìn)行交互的示例講解

    今天小編就為大家分享一篇AngularJS實(shí)現(xiàn)與后臺(tái)服務(wù)器進(jìn)行交互的示例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Angular 如何使用第三方庫(kù)的方法

    Angular 如何使用第三方庫(kù)的方法

    本篇文章主要介紹了Angular 如何使用第三方庫(kù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • AngularJS  $on、$emit和$broadcast的使用

    AngularJS $on、$emit和$broadcast的使用

    本文主要介紹AngularJS $on、$emit和$broadcast的使用,這里整理了詳細(xì)的資料及簡(jiǎn)單示例代碼有興趣的小伙伴可以參考下
    2016-09-09
  • Angular8引入百度Echarts進(jìn)行圖表分析的實(shí)現(xiàn)代碼

    Angular8引入百度Echarts進(jìn)行圖表分析的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Angular8引入百度Echarts進(jìn)行圖表分析的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • AngularJS基礎(chǔ) ng-options 指令詳解

    AngularJS基礎(chǔ) ng-options 指令詳解

    本文主要介紹AngularJS ng-options 指令,這里對(duì)ng-options指令的知識(shí)做了詳細(xì)整理,并附有詳細(xì)的代碼示例,有需要的小伙伴可以參考下
    2016-08-08
  • angular中的post請(qǐng)求處理示例詳解

    angular中的post請(qǐng)求處理示例詳解

    這篇文章主要給大家介紹了關(guān)于angular中post請(qǐng)求處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用angular具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • angularjs 源碼解析之injector

    angularjs 源碼解析之injector

    這篇文章主要介紹angular中實(shí)現(xiàn)依賴(lài)注入的”幕后英雄” — 注入器(Injector)。說(shuō)它是”幕后英雄”,是因?yàn)樗攀且蕾?lài)注入得以實(shí)現(xiàn)的主力。我們從源碼上來(lái)分析下他吧
    2016-08-08
  • AngularJS入門(mén)教程之 XMLHttpRequest實(shí)例講解

    AngularJS入門(mén)教程之 XMLHttpRequest實(shí)例講解

    本文主要講解 AngularJS XMLHttpRequest,這里給大家整理相關(guān)資料并提供實(shí)例代碼,有需要的小伙伴參考下
    2016-07-07
  • Angular?ViewChild組件間通信demo

    Angular?ViewChild組件間通信demo

    這篇文章主要為大家介紹了Angular?ViewChild組件間通信demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論