angular中常見問答題

1空盼、angularjs的幾大特性是什么?

雙向數(shù)據(jù)綁定新荤、依賴注入揽趾、模板、指令苛骨、MVC/MVVM

2篱瞎、列舉幾種常見的設(shè)計(jì)模式,寫出沒個代表的含義痒芝?

MVC :model view controller

MVVM :model view viewModel

3俐筋、請描述angularjs的運(yùn)行過程?

angularjs編譯所有的HTML元素標(biāo)簽严衬,然后在里面查找angular程序的入口 ng-app 每個元素上的指令是把所有指令收集起來根據(jù)優(yōu)先級依次編譯

4澄者、ng-bind和ng-model的區(qū)別是什么?

ng-bind只能展示數(shù)據(jù) ng-model可以操作數(shù)據(jù)

5请琳、請描述$scope的特點(diǎn)還有其最大的父類粱挡?

隨創(chuàng)建作用域創(chuàng)建的一個變量,就代表controller所代表的作用域俄精,其持有的對象和方法可在當(dāng)前及其子作用域生效

6询筏、原生js的延遲或回調(diào)在angularjs里能完美運(yùn)行嗎?怎么解決竖慧?可以用例子嫌套?

不能 需要用$apply來進(jìn)行傳播

7、{{ array | filter:{‘a(chǎn)ge’:23}:true }} 這個過濾里的true是什么意思圾旨?

是否用angular.equals進(jìn)行比較后為真才返回

8踱讨、自定義過濾創(chuàng)建后返回的是一個什么對象?

返回一個函數(shù)對象 并且函數(shù)內(nèi)要返回最后返回的對象

9碳胳、ng-repeat循環(huán)[1,3,2,4,3,4]數(shù)組會報錯嗎勇蝙?如果會怎么解決沫勿?

會因?yàn)橛兄貜?fù)的內(nèi)容 track by $index

10挨约、angular常用的服務(wù)中value和constant最大的區(qū)別是什么味混?

constant的創(chuàng)建要早于value 并且其可以在config配置中使用 value不行

11、常用服務(wù)中factory和service的最大區(qū)別是什么诫惭?

factory返回的對象當(dāng)我們使用它的時候手動初始化并返回翁锡,而service是當(dāng)我們第一次使用的時候angular幫我們初始化一次,然后以后使用的時候返回的都是這個對象夕土,factory創(chuàng)建的服務(wù)是代表的是其后面函數(shù)的返回值馆衔,這個返回值可以是任意類型,service不用返回怨绣,直接操作的就是自己

12角溃、怎么攔截服務(wù)?

在config配置里注入需要攔截的服務(wù)的名字+Provider來攔截

13篮撑、decorator的作用是什么减细?和攔截服務(wù)的區(qū)別是什么?

裝飾器不僅可以應(yīng)用在我們自己的服務(wù)上赢笨,也可以對angularjs核心服務(wù)進(jìn)行攔截未蝌、中斷甚至替換功能的操作,事實(shí)上angularjs的很多測試就是借助$provide.decorator()建立的茧妒、請寫一個配置路由的代碼段(只需要寫怎么聲明一個路由和其常用屬性的代碼段)

14萧吠、resolve的作用是什么?

如果設(shè)置了resolve屬性桐筏,angularjs會將列表中的元素都注入到控制器中纸型,列表對象可以是鍵(鍵值是會被注入到控制器中依賴的名字),也可以是工廠(即可以是一個服務(wù)的名字)

15梅忌、ngRoute默認(rèn)查找的路由是什么绊袋?$routeProvider.otherwise(’/index’)是什么作用?

是/ 設(shè)置路由的意外指向到/index

16铸鹰、$location.path(‘/home’)和$location.url(‘/home’)都可以進(jìn)行路由跳轉(zhuǎn)癌别,但是.path方法和.url方法最大的區(qū)別是什么?

.url方法:可以在跳轉(zhuǎn)的同時設(shè)置查詢串蹋笼,返回url的整個路徑展姐; 而.path方法:返回的路徑不包括?后面的部分剖毯;

17圾笨、什么是跨域,請簡要描述跨域的場景逊谋?

協(xié)議 域名 端口號有一個不一樣就是跨域擂达,也就是不同域名之間的訪問;

18胶滋、常使用的跨域方案就哪兩種板鬓?分別描述其利用的原理悲敷?

jsonp; post請求設(shè)置請求頭 ; jsonp利用的是script可以訪問外部信息的原理發(fā)送請求并且利用jsonp協(xié)議進(jìn)行數(shù)據(jù)交互 post設(shè)置請求頭跳過預(yù)請求來實(shí)現(xiàn)跨域

19俭令、請寫出$http網(wǎng)絡(luò)請求的幾種寫法后德,最少兩種

$http.(url).success(function(data){

}).error(function(error){

}) $http({ method:’’, url:url }).success(function(data){

}).error(function(error){

}) $http({ method:’*’, url:url }).then(function success(data){

},function error(error){

})

var promise = $http({ method:’get’, url:url }); promise.then(function(data){

},function(error){

}) 或者 promise.success(function(data){

}); promise.error(function(error){

});

20、ng-if 跟 ng-show/hide 的區(qū)別有哪些抄腔?

第一點(diǎn)區(qū)別是瓢湃,ng-if

在后面表達(dá)式為 true 的時候才創(chuàng)建這個 dom 節(jié)點(diǎn),ng-show

是初始時就創(chuàng)建了赫蛇,用 display:block

和 display:none

來控制顯示和不顯示绵患。

第二點(diǎn)區(qū)別是,ng-if

會(隱式地)產(chǎn)生新作用域悟耘,ng-switch

藏雏、 ng-include

等會動態(tài)創(chuàng)建一塊界面的也是如此。

這樣會導(dǎo)致作煌,在 ng-if

中用基本變量綁定 ng-model

掘殴,并在外層 div 中把此 model 綁定給另一個顯示區(qū)域,內(nèi)層改變時粟誓,外層不會同步改變奏寨,因?yàn)榇藭r已經(jīng)是兩個變量了。

{{name}}

#21鹰服、ng-show

不存在此問題病瞳,因?yàn)樗蛔詭б患壸饔糜颉?/p>

避免這類問題出現(xiàn)的辦法是,始終將頁面中的元素綁定到對象的屬性(data.x)而不是直接綁定到基本變量(x)上悲酷。

詳見 AngularJS 中的作用域

#22套菜、ng-repeat迭代數(shù)組的時候,如果數(shù)組中有相同值设易,會有什么問題逗柴,如何解決?

會提示 Duplicates in a repeater are not allowed.

加 track by $index

可解決顿肺。當(dāng)然戏溺,也可以 trace by 任何一個普通的值,只要能唯一性標(biāo)識數(shù)組中的每一項(xiàng)即可(建立 dom 和數(shù)據(jù)之間的關(guān)聯(lián))屠尊。

ng-click 中寫的表達(dá)式旷祸,能使用 JS 原生對象上的方法嗎?

不止是 ng-click 中的表達(dá)式讼昆,只要是在頁面中托享,都不能直接調(diào)用原生的 JS 方法,因?yàn)檫@些并不存在于與頁面對應(yīng)的 Controller 的 $scope 中。

舉個栗子:

{{parseInt(55.66)}}

會發(fā)現(xiàn)闰围,什么也沒有顯示赃绊。

但如果在 $scope 中添加了這個函數(shù):

$scope.parseInt = function(x){ return parseInt(x);}

這樣自然是沒什么問題了。

#23辫诅、對于這種需求凭戴,使用一個 filter 或許是不錯的選擇:

{{13.14 | parseIntFilter}}

app.filter('parseIntFilter', function(){ return function(item){ return parseInt(item); }})

{{now | 'yyyy-MM-dd'}}

這種表達(dá)式里面涧狮,豎線和后面的參數(shù)通過什么方式可以自定義炕矮?

filter,格式化數(shù)據(jù)者冤,接收一個輸入肤视,按某規(guī)則處理,返回處理結(jié)果涉枫。

內(nèi)置 filter

ng 內(nèi)置的 filter 有九種:

date(日期)

currency(貨幣)

limitTo(限制數(shù)組或字符串長度)

orderBy(排序)

lowercase(小寫)

uppercase(大寫)

number(格式化數(shù)字邢滑,加上千位分隔符,并接收參數(shù)限定小數(shù)點(diǎn)位數(shù))

filter(處理一個數(shù)組愿汰,過濾出含有某個子串的元素)

json(格式化 json 對象)

filter 有兩種使用方法困后,一種是直接在頁面里:

{{now | date : 'yyyy-MM-dd'}}

另一種是在 js 里面用:

// $filter('過濾器名稱')(需要過濾的對象, 參數(shù)1, 參數(shù)2,...)$filter('date')(now, 'yyyy-MM-dd hh:mm:ss');

24、自定義 filter

// 形式app.filter('過濾器名稱',function(){ return function(需要過濾的對象,過濾器參數(shù)1,過濾器參數(shù)2,...){ //...做一些事情 ?return 處理后的對象; }}); // 栗子app.filter('timesFilter', function(){ return function(item, times){ var result = ''; for(var i = 0; i < times; i++){ result += item; } return result; }})

25衬廷、factory摇予、service 和 provider 是什么關(guān)系?

factory

把 service 的方法和數(shù)據(jù)放在一個對象里吗跋,并返回這個對象

app.factory('FooService', function(){ return { target: 'factory', sayHello: function(){ return 'hello ' + this.target; } }});

service

通過構(gòu)造函數(shù)方式創(chuàng)建 service侧戴,返回一個實(shí)例化對象

app.service('FooService', function(){ var self = this; this.target = 'service'; this.sayHello = function(){ return 'hello ' + self.target; }});

provider

創(chuàng)建一個可通過 config 配置的 service,$get 中返回的跌宛,就是用 factory 創(chuàng)建 service 的內(nèi)容

app.provider('FooService', function(){ this.configData = 'init data'; this.setConfigData = function(data){ if(data){ this.configData = data; } } this.$get = function(){ var self = this; return { target: 'provider', sayHello: function(){ return self.configData + ' hello ' + this.target; } } }});// 此處注入的是 FooService 的 providerapp.config(function(FooServiceProvider){ FooServiceProvider.setConfigData('config data');});

從底層實(shí)現(xiàn)上來看酗宋,service 調(diào)用了 factory,返回其實(shí)例疆拘;factory 調(diào)用了 provider蜕猫,返回其 $get

中定義的內(nèi)容。factory 和 service 功能類似哎迄,只不過 factory 是普通 function丹锹,可以返回任何東西(return 的都可以被訪問,所以那些私有變量怎么寫芬失,你懂的)楣黍;service 是構(gòu)造器,可以不返回(綁定到 this 的都可以被訪問)棱烂;provider 是加強(qiáng)版 factory租漂,返回一個可配置的 factory。

詳見 AngularJS 之 Factory vs Service vs Provider

angular 的數(shù)據(jù)綁定采用什么機(jī)制?詳述原理

臟檢查機(jī)制哩治。

雙向數(shù)據(jù)綁定是 AngularJS 的核心機(jī)制之一秃踩。當(dāng) view 中有任何數(shù)據(jù)變化時,會更新到 model 业筏,當(dāng) model 中數(shù)據(jù)有變化時憔杨,view 也會同步更新,顯然蒜胖,這需要一個監(jiān)控消别。

原理就是,Angular 在 scope 模型上設(shè)置了一個 監(jiān)聽隊(duì)列台谢,用來監(jiān)聽數(shù)據(jù)變化并更新 view 寻狂。每次綁定一個東西到 view 上時 AngularJS 就會往 $watch

隊(duì)列里插入一條 $watch

,用來檢測它監(jiān)視的 model 里是否有變化的東西朋沮。當(dāng)瀏覽器接收到可以被 angular context 處理的事件時蛇券,$digest

循環(huán)就會觸發(fā),遍歷所有的 $watch

樊拓,最后更新 dom纠亚。

舉個栗子

increase 1

click 時會產(chǎn)生一次更新的操作(至少觸發(fā)兩次 $digest

循環(huán))

按下按鈕

瀏覽器接收到一個事件,進(jìn)入到 angular context

26筋夏、$digest

循環(huán)開始執(zhí)行蒂胞,查詢每個 $watch

是否變化

由于監(jiān)視 $scope

.val 的 $watch

報告了變化,因此強(qiáng)制再執(zhí)行一次 $digest

循環(huán)

新的 $digest

循環(huán)未檢測到變化

瀏覽器拿回控制器叁丧,更新 $scope

.val 新值對應(yīng)的 dom

$digest

循環(huán)的上限是 10 次(超過 10次后拋出一個異常啤誊,防止無限循環(huán))。

詳見 關(guān)于 AngularJS 的數(shù)據(jù)綁定

兩個平級界面塊 a 和 b拥娄,如果 a 中觸發(fā)一個事件蚊锹,有哪些方式能讓 b 知道?詳述原理

這個問題換一種說法就是稚瘾,如何在平級界面模塊間進(jìn)行通信牡昆。有兩種方法,一種是共用服務(wù)摊欠,一種是基于事件丢烘。

共用服務(wù)

在 Angular 中,通過 factory 可以生成一個單例對象些椒,在需要通信的模塊 a 和 b 中注入這個對象即可播瞳。

基于事件

這個又分兩種方式

第一種是借助父 controller。在子 controller 中向父 controller 觸發(fā)($emit

)一個事件免糕,然后在父 controller 中監(jiān)聽($on

)事件赢乓,再廣播($broadcast

)給子 controller 忧侧,這樣通過事件攜帶的參數(shù),實(shí)現(xiàn)了數(shù)據(jù)經(jīng)過父 controller牌芋,在同級 controller 之間傳播蚓炬。

第二種是借助 $rootScope

。每個 Angular 應(yīng)用默認(rèn)有一個根作用域 $rootScope

躺屁, 根作用域位于最頂層肯夏,從它往下掛著各級作用域。所以犀暑,如果子控制器直接使用 $rootScope

廣播和接收事件驯击,那么就可實(shí)現(xiàn)同級之間的通信。

詳見 AngularJS 中 Controller 之間的通信

一個 angular 應(yīng)用應(yīng)當(dāng)如何良好地分層母怜?

目錄結(jié)構(gòu)的劃分

對于小型項(xiàng)目余耽,可以按照文件類型組織缚柏,比如:

cssjs controllers models services filterstemplates

但是對于規(guī)模較大的項(xiàng)目苹熏,最好按業(yè)務(wù)模塊劃分,比如:

cssmodules account controllers models services filters templates disk controllers models services filters templates

modules 下最好再有一個 common 目錄來存放公共的東西币喧。

邏輯代碼的拆分

作為一個 MVVM 框架轨域,Angular 應(yīng)用本身就應(yīng)該按照 模型,視圖模型(控制器)杀餐,視圖來劃分干发。

這里邏輯代碼的拆分,主要是指盡量讓 controller 這一層很薄史翘。提取共用的邏輯到 service 中 (比如后臺數(shù)據(jù)的請求枉长,數(shù)據(jù)的共享和緩存,基于事件的模塊間通信等)琼讽,提取共用的界面操作到 directive 中(比如將日期選擇必峰、分頁等封裝成組件等),提取共用的格式化操作到 filter 中等等钻蹬。

在復(fù)雜的應(yīng)用中吼蚁,也可以為實(shí)體建立對應(yīng)的構(gòu)造函數(shù),比如硬盤(Disk)模塊问欠,可能有列表肝匆、新建、詳情這樣幾個視圖顺献,并分別對應(yīng)的有 controller旗国,那么可以建一個 Disk 構(gòu)造函數(shù),里面完成數(shù)據(jù)的增刪改查和驗(yàn)證操作注整,有跟 Disk 相關(guān)的 controller能曾,就注入 Disk 構(gòu)造器并生成一個實(shí)例嫁怀,這個實(shí)例就具備了增刪改查和驗(yàn)證方法。這樣既層次分明借浊,又實(shí)現(xiàn)了復(fù)用(讓 controller 層更薄了)塘淑。

參考 AngularJS在蘇寧云中心的深入實(shí)踐

27、angular 應(yīng)用常用哪些路由庫蚂斤,各自的區(qū)別是什么存捺?

Angular1.x 中常用 ngRoute 和 ui.router,還有一種為 Angular2 設(shè)計(jì)的 new router(面向組件)曙蒸。后面那個沒在實(shí)際項(xiàng)目中用過捌治,就不講了。

無論是 ngRoute 還是 ui.router纽窟,作為框架額外的附加功能肖油,都必須以 模塊依賴 的形式被引入。

區(qū)別

ngRoute 模塊是 Angular 自帶的路由模塊臂港,而 ui.router 模塊是基于 ngRoute模塊開發(fā)的第三方模塊森枪。

ui.router 是基于 state (狀態(tài))的, ngRoute 是基于 url 的审孽,ui.router模塊具有更強(qiáng)大的功能县袱,主要體現(xiàn)在視圖的嵌套方面。

使用 ui.router 能夠定義有明確父子關(guān)系的路由佑力,并通過 ui-view 指令將子路由模版插入到父路由模板的

中去式散,從而實(shí)現(xiàn)視圖嵌套。而在 ngRoute 中不能這樣定義打颤,如果同時在父子視圖中 使用了

會陷入死循環(huán)暴拄。

示例

ngRoute

var app = angular.module('ngRouteApp', ['ngRoute']);app.config(function($routeProvider){ $routeProvider .when('/main', { templateUrl: "main.html", controller: 'MainCtrl' }) .otherwise({ redirectTo: '/tabs' });

ui.router

var app = angular.module("uiRouteApp", ["ui.router"]);app.config(function($urlRouterProvider, $stateProvider){ $urlRouterProvider.otherwise("/index"); $stateProvider .state("Main", { url: "/main", templateUrl: "main.html", controller: 'MainCtrl' })

28、如果通過angular的directive規(guī)劃一套全組件化體系编饺,可能遇到哪些挑戰(zhàn)乖篷?

沒有自己用 directive 做過一全套組件,講不出反肋。

能想到的一點(diǎn)是那伐,組件如何與外界進(jìn)行數(shù)據(jù)的交互,以及如何通過簡單的配置就能使用吧石蔗。

分屬不同團(tuán)隊(duì)進(jìn)行開發(fā)的 angular 應(yīng)用罕邀,如果要做整合,可能會遇到哪些問題养距,如何解決诉探?

可能會遇到不同模塊之間的沖突。

比如一個團(tuán)隊(duì)所有的開發(fā)在 moduleA 下進(jìn)行棍厌,另一團(tuán)隊(duì)開發(fā)的代碼在 moduleB 下

angular.module('myApp.moduleA', []) .factory('serviceA', function(){ ... }) angular.module('myApp.moduleB', []) .factory('serviceA', function(){ ... }) angular.module('myApp', ['myApp.moduleA', 'myApp.moduleB'])

會導(dǎo)致兩個 module 下面的 serviceA 發(fā)生了覆蓋肾胯。

貌似在 Angular1.x 中并沒有很好的解決辦法竖席,所以最好在前期進(jìn)行統(tǒng)一規(guī)劃,做好約定敬肚,嚴(yán)格按照約定開發(fā)毕荐,每個開發(fā)人員只寫特定區(qū)塊代碼。

angular 的缺點(diǎn)有哪些艳馒?

強(qiáng)約束

導(dǎo)致學(xué)習(xí)成本較高憎亚,對前端不友好。

但遵守 AngularJS 的約定時弄慰,生產(chǎn)力會很高第美,對 Java 程序員友好。

不利于 SEO

因?yàn)樗袃?nèi)容都是動態(tài)獲取并渲染生成的陆爽,搜索引擎沒法爬取什往。

一種解決辦法是,對于正常用戶的訪問慌闭,服務(wù)器響應(yīng) AngularJS 應(yīng)用的內(nèi)容别威;對于搜索引擎的訪問,則響應(yīng)專門針對 SEO 的HTML頁面贡必。

性能問題

作為 MVVM 框架兔港,因?yàn)閷?shí)現(xiàn)了數(shù)據(jù)的雙向綁定庸毫,對于大數(shù)組仔拟、復(fù)雜對象會存在性能問題。

可以用來 優(yōu)化 Angular 應(yīng)用的性能 的辦法:

減少監(jiān)控項(xiàng)(比如對不會變化的數(shù)據(jù)采用單向綁定)

主動設(shè)置索引(指定 track by

飒赃,簡單類型默認(rèn)用自身當(dāng)索引利花,對象默認(rèn)使用 $$hashKey

,比如改為 track by item.id

降低渲染數(shù)據(jù)量(比如分頁载佳,或者每次取一小部分?jǐn)?shù)據(jù)炒事,根據(jù)需要再取)

數(shù)據(jù)扁平化(比如對于樹狀結(jié)構(gòu)蔫慧,使用扁平化結(jié)構(gòu)挠乳,構(gòu)建一個 map 和樹狀數(shù)據(jù),對樹操作時姑躲,由于跟扁平數(shù)據(jù)同一引用睡扬,樹狀數(shù)據(jù)變更會同步到原始的扁平數(shù)據(jù))

另外,對于Angular1.x 黍析,存在 臟檢查 和 模塊機(jī)制 的問題卖怜。

移動端

可嘗試 Ionic,但并不完善阐枣。

參考 如何看2015年1月Peter-Paul Koch對Angular的看法马靠?

如何看待 angular 1.2 中引入的 controller as 語法奄抽?

最根本的好處

在 angular 1.2 以前,在 view 上的任何綁定都是直接綁定在 $scope

上的

function myCtrl($scope){ $scope.a = 'aaa'; $scope.foo = function(){ ... }}

使用 controllerAs甩鳄,不需要再注入 $scope

逞度,controller 變成了一個很簡單的 javascript 對象(POJO),一個更純粹的 ViewModel妙啃。

function myCtrl(){ // 使用 vm 捕獲 this 可避免內(nèi)部的函數(shù)在使用 this 時導(dǎo)致上下文改變 var vm = this; vm.a = 'aaa';}

原理

從源碼實(shí)現(xiàn)上來看第晰,controllerAs 語法只是把 controller 這個對象的實(shí)例用 as 別名在 $scope 上創(chuàng)建了一個屬性。

if (directive.controllerAs) { locals.$scope[directive.controllerAs] = controllerInstance;}

但是這樣做彬祖,除了上面提到的使 controller 更加 POJO 外茁瘦,還可以避免遇到 AngularJS 作用域相關(guān)的一個坑(就是上文中 ng-if 產(chǎn)生一級作用域的坑葬馋,其實(shí)也是 javascript 原型鏈繼承中值類型繼承的坑扒怖。因?yàn)槭褂?controllerAs 的話 view 上所有字段都綁定在一個引用的屬性上,比如 vm.xx聋袋,所以坑不再存在)突倍。

{{name}}

?

問題

使用 controllerAs 會遇到的一個問題是腔稀,因?yàn)闆]有注入 $scope

,導(dǎo)致 $emit

羽历、 $broadcast

焊虏、 $on

、 $watch

等 $scope

下的方法無法使用秕磷。這些跟事件相關(guān)的操作可以封裝起來統(tǒng)一處理诵闭,或者在單個 controller 中引入 $scope

,特殊對待澎嚣。

參考 angular controller as syntax vs scope

詳述 angular 的 “依賴注入”

栗子

依賴注入是一種軟件設(shè)計(jì)模式疏尿,目的是處理代碼之間的依賴關(guān)系,減少組件間的耦合易桃。

舉個栗子褥琐,如果沒有使用 AngularJS,想從后臺查詢數(shù)據(jù)并在前端顯示晤郑,可能需要這樣做:

var animalBox = document.querySelector('.animal-box');var httpRequest = { get: function(url, callback){ console.log(url + ' requested'); var animals = ['cat', 'dog', 'rabbit']; callback(animals); }}var render = function(el, http){ http.get('/api/animals', function(animals){ el.innerHTML = animals; })}render(httpRequest, animalBox);

但是敌呈,如果在調(diào)用 render 的時候不傳參數(shù),像下面這樣造寝,會報錯磕洪,因?yàn)檎也坏?el 和 http(定義的時候依賴了,運(yùn)行的時候不會自動查找依賴項(xiàng))

render();// TypeError: Cannot read property 'get' of undefined

而使用 AngularJS匹舞,可以直接這樣

function myCtrl = ($scope, $http){ $http.get('/api/animals').success(function(data){ $scope.animals = data; })}

也就是說褐鸥,在 Angular App 運(yùn)行的時候,調(diào)用 myCtrl赐稽,自動做了 $scope

和 $http

兩個依賴性的注入叫榕。

原理

AngularJS 是通過構(gòu)造函數(shù)的參數(shù)名字來推斷依賴服務(wù)名稱的浑侥,通過 toString()

來找到這個定義的 function 對應(yīng)的字符串,然后用正則解析出其中的參數(shù)(依賴項(xiàng))晰绎,再去依賴映射中取到對應(yīng)的依賴寓落,實(shí)例化之后傳入。

簡化一下荞下,大概是這樣:

var inject = { // 存儲依賴映射關(guān)系 storage: {}, // 注冊依賴 register: function(name, resource){ this.storage[name] = resource; }, // 解析出依賴并調(diào)用 resolve: function(target){ var self = this; var FN_ARGS = /^function\s[^=XXFN}(\s({FNXX=]))/m; var STRIP_COMMENTS = /((\/\/.$)|(\/*[\s\S]?*\/))/mg; fnText = target.toString().replace(STRIP_COMMENTS, ''); argDecl = fnText.match(FN_ARGS)[1].split(/, ?/g); var args = []; argDecl.forEach(function(arg){ if(self.storage[arg]){ args.push(self.storage[arg]); } }) return function(){ target.apply({}, args); } }}

使用這個 injector伶选,前面那個不用 AngularJS 的栗子這樣改造一下就可以調(diào)用了

inject.register('el', animalBox);inject.register('ajax', httpRequest);render = inject.resolve(render);render();

問題

因?yàn)?AngularJS 的 injector 是假設(shè)函數(shù)的參數(shù)名就是依賴的名字,然后去查找依賴項(xiàng)尖昏,那如果按前面栗子中那樣注入依賴仰税,代碼壓縮后(參數(shù)被重命名了),就無法查找到依賴項(xiàng)了抽诉。

// 壓縮前function myCtrl = ($scope, $http){ ...}// 壓縮后function myCtrl = (a, b){ ...}

所以陨簇,通常會使用下面兩種方式注入依賴(對依賴添加的順序有要求)。

數(shù)組注釋法

myApp.controller('myCtrl', ['$scope', '$http', function($scope, $http){ ...}])

顯式 $inject

myApp.controller('myCtrl', myCtrl);function myCtrl = ($scope, $http){ ...}myCtrl.$inject = ['$scope', '$http'];

29迹淌、補(bǔ)充

對于一個 DI 容器河绽,必須具備三個要素:依賴項(xiàng)的注冊,依賴關(guān)系的聲明和對象的獲取唉窃。

在 AngularJS 中耙饰,module 和 $provide 都可以提供依賴項(xiàng)的注冊;內(nèi)置的 injector 可以獲取對象(自動完成依賴注入)纹份;依賴關(guān)系的聲明苟跪,就是前面問題中提到的那樣。

下面是個栗子

// 對于 module矮嫉,傳遞參數(shù)不止一個削咆,代表新建模塊,空數(shù)組代表不依賴其他模塊// 只有一個參數(shù)(模塊名)蠢笋,代表獲取模塊// 定義 myApp,添加 myApp.services 為其依賴項(xiàng)angular.module('myApp', ['myApp.services']);// 定義一個 services module鳞陨,將 services 都注冊在這個 module 下面angular.module('myApp.services', [])// $provider 有 factory, service, provider, value, constant// 定義一個 HttpServiceangular.module('myApp.services').service('HttpService', ['$http', function($http){ ...}])

30昨寞、參考

[AngularJS] 自己實(shí)現(xiàn)一個簡單的依賴注入

理解angular中的module和injector,即依賴注入

AngularJS中的依賴注入實(shí)際應(yīng)用場景

31厦滤、如何看待angular2

相比 Angular1.x援岩,Angular2的改動很大,幾乎算是一個全新的框架掏导。

基于 TypeScript(可以使用 TypeScript 進(jìn)行開發(fā))享怀,在大型項(xiàng)目團(tuán)隊(duì)協(xié)作時,強(qiáng)語言類型更有利趟咆。

組件化添瓷,提升開發(fā)和維護(hù)的效率梅屉。

還有 module 支持動態(tài)加載,new router鳞贷,promise的原生支持等等坯汤。

迎合未來標(biāo)準(zhǔn),吸納其他框架的優(yōu)點(diǎn)搀愧,值得期待惰聂,不過同時要學(xué)習(xí)的東西也更多了(ES next、TS咱筛、Rx等)搓幌。

參考

浴火重生的Angular

有關(guān)Angular 2.0的一切

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市迅箩,隨后出現(xiàn)的幾起案子鼻种,更是在濱河造成了極大的恐慌,老刑警劉巖沙热,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叉钥,死亡現(xiàn)場離奇詭異,居然都是意外死亡篙贸,警方通過查閱死者的電腦和手機(jī)投队,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爵川,“玉大人敷鸦,你說我怎么就攤上這事∏薰保” “怎么了扒披?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長圃泡。 經(jīng)常有香客問我碟案,道長,這世上最難降的妖魔是什么颇蜡? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任价说,我火速辦了婚禮,結(jié)果婚禮上风秤,老公的妹妹穿的比我還像新娘鳖目。我一直安慰自己,他們只是感情好缤弦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布领迈。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狸捅。 梳的紋絲不亂的頭發(fā)上衷蜓,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音薪贫,去河邊找鬼恍箭。 笑死,一個胖子當(dāng)著我的面吹牛瞧省,可吹牛的內(nèi)容都是我干的扯夭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼鞍匾,長吁一口氣:“原來是場噩夢啊……” “哼交洗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起橡淑,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤构拳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梁棠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體置森,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年符糊,在試婚紗的時候發(fā)現(xiàn)自己被綠了凫海。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡男娄,死狀恐怖行贪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情模闲,我是刑警寧澤建瘫,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站尸折,受9級特大地震影響啰脚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翁授,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一拣播、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧收擦,春花似錦、人聲如沸谍倦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昼蛀。三九已至宴猾,卻和暖如春圆存,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仇哆。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工沦辙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讹剔。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓油讯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親延欠。 傳聞我的和親對象是個殘疾皇子陌兑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容