導航:首頁 > 編程語言 > angularjs控制器初始化

angularjs控制器初始化

發布時間:2024-05-01 11:01:43

❶ angularjs 鎴愬姛lazyload鍔犺澆浜嗘帶鍒跺櫒js 浣嗘槸鎺у埗鍣ㄦ湭瀹氫箟

鎸囦護鍜屾帶鍒跺櫒鐨勪氦浜 婊戝姩鍔犺澆 涓婇潰鐨勪唬鐮佸鉤娣℃棤濂囷紝鏈変釜鎺у埗鍣ㄦ湁涓鎸囦護錛坙oader錛夛紝涓嬮潰鍙浠ョ湅鍒版垜浠閫氳繃 directive鍒涘緩浜嗚繖涓鎸囦護錛屽苟涓旀垜浠閫氳繃link鐨勬柟娉曠粰浠栬祴鍊奸紶鏍囦簨浠(mouseenter)銆 var myMole = angular.mole('MyController',[]); myMole.controller('MyCtrl',function($scope){ $scope.loadData = function(){ console.log("鍔犺澆鏁版嵁..."); } }) myMole.directive('loader',function(){ return{ restrict:'AE', link:function(scope,element,attr){ element.bind('mouseenter',function(){ scope.loadData(); }) } } }) 鎴戜滑鏉ョ湅鐪嬭繍琛岀殑緇撴灉錛宱k錛屾垜浠鎵撳嵃鍑烘潵 "鍔犺澆鏁版嵁...

❷ 濡備綍浣跨敤AngularJs鎵撻犳潈闄愮$悊緋葷粺銆愮畝鏄撳瀷銆慱AngularJS


涓銆佸紩璦

鏈鏂囧皢浠嬬粛濡備綍鎶夾ngularJs搴旂敤鍒板疄闄呴」鐩涓銆傛湰綃囨枃絝犲皢浣跨敤AngularJS鏉ユ墦閫犱竴涓綆鏄撶殑鏉冮檺綆$悊緋葷粺銆備笅闈涓嶅氳達紝鐩存帴榪涘叆涓婚樸

浜屻佹暣浣撴灦鏋勮捐′粙緇

棣栧厛鐪嬩笅鏁翠釜欏圭洰鐨勬灦鏋勮捐″浘錛




浠庝笂鍥懼彲浠ョ湅鍑烘暣涓欏圭洰鐨勪竴涓鏁翠綋緇撴瀯錛屾帴涓嬫潵錛屾垜鏉ヨ︾粏浠嬬粛浜嗛」鐩鐨勬暣浣撴灦鏋勶細

閲囩敤Asp.net Web API鏉ュ疄鐜癛EST 鏈嶅姟銆傝繖鏍風殑瀹炵幇鏂瑰紡錛屽凡杈懼埌鍚庣鏈嶅姟鐨勫叕鐢ㄣ佸垎鍒閮ㄧ講鍜屾洿濂藉湴鎵╁睍銆俉eb灞備緷璧栧簲鐢ㄦ湇鍔℃帴鍙o紝騫朵笖浣跨敤Castle Windsor瀹炵幇渚濊禆娉ㄥ叆銆

鏄劇ず灞(鐢ㄦ埛UI)

鏄劇ず灞傞噰鐢ㄤ簡AngularJS鏉ュ疄鐜扮殑SPA欏甸潰銆傛墍鏈夌殑欏甸潰鏁版嵁閮芥槸寮傛ュ姞杞藉拰灞閮ㄥ埛鏂幫紝榪欐牱鐨勫疄鐜板皢浼氭湁鏇村ソ鐨勭敤鎴蜂綋楠屻

搴旂敤灞(Application Service)

AngularJS閫氳繃Http鏈嶅姟鍘昏鋒眰Web API鏉ヨ幏寰楁暟鎹錛岃學eb API鐨勫疄鐜板垯鏄璋冪敤搴旂敤灞傛潵璇鋒眰鏁版嵁銆

鍩虹鏋舵瀯灞

鍩虹鏋舵瀯灞傚寘鎷浠撳偍鐨勫疄鐜板拰涓浜涘叕鐢ㄦ柟娉曠殑瀹炵幇銆

浠撳偍灞傜殑瀹炵幇閲囩敤EF Code First鐨勬柟寮忔潵瀹炵幇鐨勶紝騫朵嬌鐢‥F Migration鐨勬柟寮忔潵鍒涘緩鏁版嵁搴撳拰鏇存柊鏁版嵁搴撱

LH.Common灞傚疄鐜頒簡涓浜涘叕鐢ㄧ殑鏂規硶錛屽傛棩蹇楀府鍔╃被銆佽〃杈懼紡鏍戞墿灞曠瓑綾葷殑瀹炵幇銆

棰嗗煙灞

棰嗗煙灞備富瑕佸疄鐜頒簡璇ラ」鐩鐨勬墍鏈夐嗗煙妯″瀷錛屽叾涓鍖呮嫭棰嗗煙妯″瀷鐨勫疄鐜板拰浠撳偍鎺ュ彛鐨勫畾涔夈

浠嬬粛瀹屾暣浣撶粨鏋勫栵紝鎺ヤ笅鏉ュ皢鍒嗗埆浠嬬粛璇ラ」鐩鐨勫悗絝鏈嶅姟瀹炵幇鍜學eb鍓嶇鐨勫疄鐜般

涓夈佸悗絝鏈嶅姟瀹炵幇

鍚庣鏈嶅姟涓昏侀噰鐢ˋsp.net Web API鏉ュ疄鐜板悗絝鏈嶅姟錛屽苟涓旈噰鐢–astle Windsor鏉ュ畬鎴愪緷璧栨敞鍏ャ

榪欓噷鎷挎潈闄愮$悊涓鐨勭敤鎴風$悊鏉ヤ粙緇峈est Web API鏈嶅姟鐨勫疄鐜般

鎻愪緵鐢ㄦ埛鏁版嵁鐨凴EST鏈嶅姟鐨勫疄鐜幫細

浠庝笂闈浠g爜瀹炵幇鍙浠ョ湅鍑猴紝User REST 鏈嶅姟渚濊禆涓嶪UserService鎺ュ彛錛屽苟涓斾篃娌℃湁鍍忎紶緇熺殑鏂瑰紡灝嗘墍鏈夌殑涓氬姟閫昏緫鏀懼湪Web API瀹炵幇涓錛岃屾槸灝嗗叿浣撶殑涓浜涗笟鍔″疄鐜板皝瑁呭埌瀵瑰簲鐨勫簲鐢ㄥ眰涓錛孯est API鍙璐熻矗璋冪敤瀵瑰簲鐨勫簲鐢ㄥ眰涓鐨勬湇鍔°傝繖鏍瘋捐″ソ澶勬湁錛

REST 鏈嶅姟閮ㄤ緷璧栦笌搴旂敤灞傛帴鍙o紝浣垮緱鑱岃矗鍒嗙伙紝灝嗗簲鐢ㄥ眰鏈嶅姟鐨勫疄渚嬪寲浜ょ粰鍗曠嫭鐨勪緷璧栨敞鍏ュ瑰櫒鍘誨畬鎴愶紝鑰孯EST鏈嶅姟鍙璐熻矗璋冪敤瀵瑰簲搴旂敤鏈嶅姟鐨勬柟娉曟潵鑾峰彇鏁版嵁銆傞噰鐢ㄤ緷璧栨帴鍙h屼笉渚濊禆涓庡叿浣撶被鐨勫疄鐜幫紝浣垮緱綾諱笌綾諱箣闂翠綆鑰﹀悎銆俁EST鏈嶅姟鍐呬笉鍖呮嫭鍏蜂綋鐨勪笟鍔¢昏緫瀹炵幇銆傝繖鏍風殑璁捐″彲浠ヤ嬌寰楁湇鍔℃洿濂藉湴鍒嗙伙紝濡傛灉浣犲悗鏈熸兂鐢╓CF鏉ュ疄鐜癛EST鏈嶅姟鐨勶紝榪欐牱灝變笉闇瑕侀噸澶嶅湪WCF鐨凴EST鏈嶅姟綾諱腑閲嶅嶅啓涓綃嘩eb API涓鐨勯昏緫浜嗭紝榪欐椂鍊欏畬鍏ㄥ彲浠ヨ皟鐢ㄥ簲鐢ㄦ湇鍔$殑鎺ュ彛鏂規硶鏉ュ疄鐜癢CF REST鏈嶅姟銆傛墍浠ュ皢涓氬姟閫昏緫瀹炵幇鎶藉埌搴旂敤鏈嶅姟灞傚幓瀹炵幇錛岃繖鏍風殑璁捐″皢浣垮緱REST 鏈嶅姟鑱岃矗鏇村姞鍗曚竴錛孯EST鏈嶅姟瀹炵幇鏇村規槗鎵╁睍銆

鐢ㄦ埛搴旂敤鏈嶅姟鐨勫疄鐜幫細

榪欓噷搴旂敤鏈嶅姟灞傚叾瀹炶繕鍙浠ヨ繘涓姝ョ殑浼樺寲錛屽疄鐜頒唬鐮佸眰綰х殑璇誨啓鍒嗙伙紝瀹氫箟IReadOnlyService鎺ュ彛鍜孖WriteServie鎺ュ彛錛屽苟涓旀妸鍐欐搷浣滃彲浠ラ噰鐢ㄦ硾鍨嬫柟娉曠殑鏂瑰紡鎶借薄鍒癇aseService涓鍘誨疄鐜般傝繖鏍蜂竴浜涘炲垹鏀規搷浣滃疄鐜板叕鐢錛屼箣鎵浠ュ彲浠ュ皢榪欓噷鎿嶄綔瀹炵幇鍏鐢錛屾槸鍥犱負榪欎簺鎿嶄綔閮芥槸闈炲父綾諱技鐨勶紝鏃犻潪鏄鎿嶄綔鐨勫疄浣撲笉涓鏍風艦浜嗐傚叾瀹炶繖鏍風殑瀹炵幇鍦ㄦ垜鍙︿竴涓寮婧愰」鐩涓宸茬粡鐢ㄥ埌錛歄nlineStore.澶у跺彲浠ュ弬鑰冭繖涓鑷琛屽幓瀹炵幇銆


浠撳偍灞傜殑瀹炵幇錛

鐢ㄦ埛搴旂敤鏈嶅姟涔熸病鏈夌洿鎺ヤ緷璧栦笌鍏蜂綋鐨勪粨鍌ㄧ被錛屽悓鏍蜂篃鏄渚濊禆鍏舵帴鍙c傚瑰簲鐨勭敤鎴蜂粨鍌ㄧ被鐨勫疄鐜板備笅錛

鍥涖丄ngularJS鍓嶇瀹炵幇

Web鍓嶇鐨勫疄鐜板氨鏄閲囩敤AngularJS鏉ュ疄鐜幫紝騫朵笖閲囩敤妯″潡鍖栧紑鍙戞ā寮忋傚叿浣揥eb鍓嶇鐨勪唬鐮佺粨鏋勫備笅鍥炬墍紺猴細



浣跨敤AngularJS寮鍙戠殑Web搴旂敤紼嬪簭鐨勪唬鐮佷箣闂寸殑璋冪敤灞傛″拰鍚庣鍩烘湰涓鑷達紝涔熸槸瑙嗗浘欏甸潰鈥斺斻嬫帶鍒跺櫒妯″潡鈥斺斻嬫湇鍔℃ā鍧椻斺斻媁eb API鏈嶅姟銆

騫朵笖Web鍓嶇疌SS鍜孞S璧勬簮鐨勫姞杞介噰鐢ㄤ簡Bundle鐨勬柟寮忔潵鍑忓皯璇鋒眰璧勬簮鐨勬℃暟錛屼粠鑰屽姞蹇欏甸潰鍔犺澆鏃墮棿銆傚叿浣揃undle綾葷殑閰嶇疆錛

棣栭〉 Index.cshtml


浜斻佽繍琛屾晥鏋

浠嬬粛瀹屽墠鍚庣鐨勫疄鐜頒箣鍚庯紝鎺ヤ笅鏉ヨ╂垜浠鐪嬩笅鏁翠釜欏圭洰鐨勮繍琛屾晥鏋滐細



鍏銆佹葷粨

鍒版わ紝鏈鏂囩殑鎵鏈夊唴瀹歸兘浠嬬粛瀹屼簡錛屽敖綆℃湰鏂囩殑AngularJS鐨勫簲鐢ㄩ」鐩榪樻湁寰堝氬畬鍠勭殑鍦版柟錛屼緥濡傛病鏈夌紦鍐茬殑鏀鎸併佹病鏈夊疄鐜拌誨啓鍒嗙伙紝娌℃湁瀵逛竴浜汚PI榪涜屽帇鍔涙祴璇曠瓑銆備絾AngularJS鍦ㄥ疄闄呴」鐩涓鐨勫簲鐢ㄥ熀鏈鏄榪欐牱鐨勶紝澶у跺傛灉鍦ㄩ」鐩涓鏈夐渶瑕佺敤鍒癆ngularJS錛屾eソ浣犱滑鍏鍙哥殑鍚庡彴鍙堟槸.NET鐨勮瘽錛岀浉淇℃湰鏂囩殑鍒嗕韓鍙浠ユ槸涓涓寰堝ソ鐨勫弬鑰冦傚彟澶栵紝鍏充簬鏋舵瀯鐨勮捐′篃鍙浠ュ弬鑰冩垜鐨勫彟涓涓寮婧愰」鐩錛歄nlineStore鍜孎astWorks銆

❸ 怎麼在angularjs的config中使用service

Angular中有幾種不同類型的services。每一種都有自己的獨特用法。

需要記住的非常重要的一點是service總是一個單體,無論是哪種類型的service。
注釋:單體是一種設計模式,它限制了每一個類僅能夠實例化為一個對象。無論我們在什麼地方注入我們的service,將永遠使用同一個實例。
例子:
app.constant('fooConfig',{
config1: true,
config2: "Default config2" });

Constant是一個非常有用的service,它經常被用來在指令中提供默認配置。因此如果你正在創建一個指令,並且你想要在給指令傳遞可選參數的同時進行一個默認配置,一個Constant就是一個好辦法。
作為一個constant,我們放入其中的值將不會改變。Contant service 基本上回事一個基本類型的值或者是一個對象。
例子:
app.value('fooConfig',{
config1: true,
config2: "Default config2 but it can change" });

一個value service有點像是一個constant但是它是可以被改變的。它也經常被用在一個指令上面,來進行配置。一個value service有點像是一個factory service的縮小版,它經常用來保存值但是我們不能在其中對值進行計算。
我們可以使用angular對象的extend方法來改變一個value service:
app = angular.mole("app", []);

app.controller('MainCtrl', function($scope, fooConfig) { $scope.fooConfig = fooConfig;
angular.extend(fooConfig, {config3: "I have been extended"});
});

app.value('fooConfig', {
config1: true,
config2: "Default config2 but it can changes" });
例子:
app.factory('foo', function() { var thisIsPrivate = "Private"; function getPrivate() { return thisIsPrivate;
} return {
variable: "This is public",
getPrivate: getPrivate
};
});
// or..
app.factory('bar', function(a) { return a * 2;
});

Factory service是最普遍使用的service。它同樣也非常容易理解。

一個Factory是一個能夠返回任何數據類型的service。對於你如何創建它並沒有什麼可選項,你僅僅需要在其中返回一些東西即可。

正如前面所說的,所有的service類型都是單體,因此如果我們在一個地方修改了foo.variable,其他的地方也會相應的發生改變。
例子:
app.service('foo', function() { var thisIsPrivate = "Private"; this.variable = "This is public"; this.getPrivate = function() { return thisIsPrivate;
};
});

Service service 和factory差不多。它們之間的區別在於service會接收一個構造器,因此當你第一次使用它的時候,它將會自動運行newFoo()來實例化一個對象。一定要記住如果你在其他的地方也使用了這個service,它將返回同一個對象。
事實上,上面的代碼和下面的代碼等價:
app.factory('foo2', function() { return new Foobar();
}); function Foobar() { var thisIsPrivate = "Private"; this.variable = "This is public"; this.getPrivate = function() { return thisIsPrivate;
};
}

Foobar是一個類,我們在首次使用它的時候在我們的factory中將它實例化然後將它返回。和service一樣,Foobar將只會實例化一次然後下次當我們再次使用factory時它將返回同一個實例。
如果我們已經有了一個類,並且我們想將它用在service中,我們只需要編寫如下的代碼:
app.service('foo3',Foobar);

Provider是factory的加強版。事實上,上一個例子中的factory代碼等價於下面的provider代碼:
app.provider('foo', function() { return { $get: function() { var thisIsPrivate = "Private"; function getPrivate() { return thisIsPrivate;
} return {
variable: "This is public",
getPrivate: getPrivate
};
}

};

});

一個provider中應當由一個$get函數,其中的內容就是我們想要注入我們應用中的部分,因此當我們將foo注入一個控制器時,我們實際上注入的是$get函數。
既然factory如此簡單,那我們為什麼還要使用provider呢?因為我們可以在config階段配置一個provider。因此我們可以編寫下面的代碼:
app.provider('foo', function() { var thisIsPrivate = "Private"; return {

setPrivate: function(newVal) { thisIsPrivate = newVal;
}, $get: function() { function getPrivate() { return thisIsPrivate;
} return {
variable: "This is public",
getPrivate: getPrivate
};
}

};

});

app.config(function(fooProvider) { fooProvider.setPrivate('New value from config');
});

在這里我們將thisIsPrivate移到了我們的$get函數的外面,然後我們創建了一個setPrivate來在一個config函數中修改thisIsPrivate。為什麼我們需要這樣做?這難道不比在factory中添加setter要容易嗎?除此之外,還有另外一個原因。

我們想要注入一個特定的對象但是我們想要提供一種方式來根據我們的需求進行一些配置。例如:一個service包含了一個使用jsonp的資源,我們想要配置具體使用的URL,或者我們想要使用一個第三方的service比如restangular來允許我們根據我們的需求來進行配置。

要注意到我們在config函數中放入的是nameProvider而不是name。在這里,我們實際上還是對name進行配置。

看到這里我們其實已經意識到了我們已經在應用中進行過一些配置了,像是$routeProvider以及$locationProvider,兩者分別用來配置我們的路由了html5模式。

那麼現在已經決定要使用前面的 foo service,但是其中還是缺少一個你想要的greet函數。你可以修改factory嗎?答案是不行!但是你可以裝飾它:
app.config(function($provide){ $provide.decorator('foo',function($delegate){ $delegate.greet = function(){ return "Hello, I am a new function of 'foo'";
}
});
});

$provide是Angular用來在內部創建我們的service的東西。如果我們想要使用它的話可以手動來使用它或者僅僅使用在我們的模塊中提供的函數(我們需要使用$provide來進行裝飾)。$provide有一個函數,decorator,它讓我們可以裝飾我們的service。它接收我們想要裝飾的service的名字並且在回調函數中接收一個$delegate來代表我們實際上的service實例。

在這里我們可以做一切我們想要的事情來裝飾我們的service。在上面的例子中,我們為我們原來的service添加了一個greet函數。接著我們返回了修改後的service。

經過修改以後,現在我們的factory中已經有了一個叫做greet的函數。

裝飾一個service的能力是非常實用的,尤其是當我們想要使用第三方的service時,此時我們不需要將代碼復制到我們的項目中,而只需要進行一些修改即可。

注意:constant service不能被裝飾。

我們的services都是單體但是我們可以創建一個單體factory來創建新的實例。在你深入之前,記住Angular中的服務都是單體並且我們不想改變這一點。但是,在極少數的情況下你需要生成一個新的實例,你可以像下面這樣做:
function Person(json){ angular.extend(this,json);
}

Person.prototype = {
update: function(){ this.name = "Dave"; this.country = "Canada";
}
};

Person.getById = function(id){ return new Person({
name: "Jesus",
country: "Spain" });
};
app.factory('personService',function(){ return {
getById: Person.getById
};
});

在這里我們創建了一個Person對象,它接收一些json數據來初始化對象。然後我們在我們的原型(原型中的函數可以被Person的實例所用)中創建了一個函數,並且在Person上直接創建了一個函數(就像是類函數一樣)。

因此現在我們擁有了一個類函數,它將基於我們提供的id來創建一個新的Person對象,並且每一個對象都可以自我更新。現在我們僅僅需要創建一個能夠使用它的service。

當每次我們調用personService.getById時,我們都在創建一個新的Person對象,因此你可以在不同的控制器中使用這個service,即便當factory是一個單體,它也能生成新的對象。

Service是Angular中最酷的特性之一。我們可以使用很多方法來創造它們,我們僅僅需要找到符合我們需求的方法然後實現它。

❹ angularjs中run方法有什麼作用

run方法用於初始化全局的抄數據,僅對全局作用域起作用。

舉個栗子吧:

<script type="text/javascript">
var m1 = angular.mole('myApp',[]);
m1.run(['$rootScope',function($rootScope){
$rootScope.name = 'hello';
}]);
console.log( m1 );
</script>

❺ 如何在 AngularJS 中對控制器進行單元測試

Instant Karma

Karma 是來Angular團隊針對JavaScript開發的一個測試運行框架。它很方便的實現了自動執行測試任務從而替代了繁瑣的手工操作(好比回歸測試集或是載入目標測試的依賴關系)Karma 和Angular的協作就好比花生醬和果凍.
只需要在Karma中定義好配置文件啟動它,接下來它就會在預期的測試環境下的自動執行測試用例。你可以在配置文件中制定相關的測試環境。angular-seed,是我強烈推薦的可以快速實施的方案。在我近期的項目中Karma 的配置如下:

mole.exports = function(config) {
config.set({
basePath: '../',

files: [
'app/lib/angular/angular.js',
'app/lib/angular/angular-*.js',
'app/js/**/*.js',
'test/lib/recaptcha/recaptcha_ajax.js',
'test/lib/angular/angular-mocks.js',
'test/unit/**/*.js'
],

exclude: [
'app/lib/angular/angular-loader.js',
'app/lib/angular/*.min.js',
'app/lib/angular/angular-scenario.js'
],

autoWatch: true,

frameworks: ['jasmine'],

browsers: ['PhantomJS'],

plugins: [
'karma-junit-reporter',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine',
'karma-phantomjs-launcher'
],

junitReporter: {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}

})
}

這個跟angular-seed的默認配置類似只不過有以下幾點不同:
需要更改瀏覽器從Chrome 轉到PhantomJS, 這樣每次跳轉時無需再打開新的瀏覽器窗口,但在OSX系統會有窗口延遲。所以這個插件還有瀏覽器設置都做了更改。
由於我的應用需要引用Google的Recaptcha服務因此添加了依賴的recaptcha_ajax.js小文件。這個小配置就像在Karma的配置文件中添加一行代碼那麼簡單。
autoWatch確實是個很酷的設置,它會讓Karma在有文件更改時自動回歸你的測試用例。你可以這樣安裝Karma:

用Jasmine設計測試用例
當使用Jasmine----一種行為驅動開發模式的JavaScript測試框架為Angular設計單元測試用例時大部分 的資源都已可獲取。
這也就是我接下來要說的話題。
如果你要對AngularJS controller做單元測試可以利用Angular的依賴注入dependency injection 功能導入測試場景中controller需要的服務版本還能同時檢查預期的結果是否正確。例如,我定義了這個controller去高亮需要導航去的那個頁簽:

app.controller('NavCtrl', function($scope, $location) {
$scope.isActive = function(route) {
return route === $location.path();
};
})

如果想要測試isActive方法,我會怎麼做呢?我將檢查$locationservice 變數是否返回了預期值,方法返回的是否預期值。因此在我們的測試說明中我們會定義好局部變數保存測試過程中需要的controlled版本並在需要時注入到對應的controller當中。然後在實際的測試用例中我們會加入斷言來驗證實際的結果是否正確。整個過程如下:

describe('NavCtrl', function() {
var $scope, $location, $rootScope, createController;

beforeEach(inject(function($injector) {
$location = $injector.get('$location');
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();

var $controller = $injector.get('$controller');

createController = function() {
return $controller('NavCtrl', {
'$scope': $scope
});
};
}));

it('should have a method to check if the path is active', function() {
var controller = createController();
$location.path('/about');
expect($location.path()).toBe('/about');
expect($scope.isActive('/about')).toBe(true);
expect($scope.isActive('/contact')).toBe(false);
});
});
使用整個基本的結構,你就能設計各種類型的測試。由於我們的測試場景使用了本地的環境來調用controller,你也可以多加上一些屬性接著執行一個方法清除這些屬性,然後再驗證一下屬性到底有沒有被清除。

那麼要是你在調用$httpservice請求或是發送數據到服務端呢?還好,Angular提供了一種
$httpBackend的mock方法。這樣的話,你就能自定義服務端的響應內容,又或是確保服務端的響應結果能和單元測試中的預期保持一致。
具體細節如下:

describe('MainCtrl', function() {
var $scope, $rootScope, $httpBackend, $timeout, createController;
beforeEach(inject(function($injector) {
$timeout = $injector.get('$timeout');
$httpBackend = $injector.get('$httpBackend');
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();

var $controller = $injector.get('$controller');

createController = function() {
return $controller('MainCtrl', {
'$scope': $scope
});
};
}));

afterEach(function() {
$httpBackend.();
$httpBackend.verifyNoOutstandingRequest();
});

it('should run the Test to get the link data from the go backend', function() {
var controller = createController();
$scope.urlToScrape = 'success.com';

$httpBackend.expect('GET', '/slurp?urlToScrape=http:%2F%2Fsuccess.com')
.respond({
"success": true,
"links": ["www.google.com", "angularjs.org", "amazon.com"]
});

// have to use $apply to trigger the $digest which will
// take care of the HTTP request
$scope.$apply(function() {
$scope.runTest();
});

expect($scope.parseOriginalUrlStatus).toEqual('calling');

$httpBackend.flush();

expect($scope.retrievedUrls).toEqual(["www.google.com", "angularjs.org", "amazon.com"]);
expect($scope.parseOriginalUrlStatus).toEqual('waiting');
expect($scope.doneScrapingOriginalUrl).toEqual(true);
});
});
正如你所見,beforeEach call其實都很類似,唯一不同的是我們是從injector獲取$httpBackend而並非直接獲取。即使如此,創建不同的測試時還會有一些明顯的不同之處。對初學者來說,會有一個afterEachcall 方法來確保$httpBackend在每次用例執行後不會有明顯的異常請求。如果你觀察一下測試場景的設置和$httpBackend方法的應用就會會發現有那麼幾點不是那麼直觀的。

實際上調用$httpBackend的方法也算是簡單明了但還不夠——我們還得在傳值給$scope.$apply的方法中把調用封裝到實際測試中的$scope.runTest方法上。這樣在$digest被觸發後才能處理HTTP請求。而如你所見直到我們調用$httpBackend.flush()方法後$httpBackend才會被解析,這也就保證了我們能在調用過程中去驗證返回的結果是否正確(在上面的示例中,controller的$scope.屬性將被傳遞給調用者,我們也因此能實時監控)
接下來的幾行代碼都是在調用過程中檢測$scopethat屬性的斷言。很酷吧?
提示:在某些單元測試中,用戶習慣把沒有$的范圍標記為變數。這個在Angular文檔中並沒有強制要求或是過分強調,只是我在使用中為了提高可讀性和一致性才使用$scopelike這種方式。

結論

也許這就是我做起來對其他人而言只是自然而然能做到的事情之一,但是學習使用Angular編寫單元測試一開始對我而言確實是相當痛苦的。我發現自己對如何開始的理解大多來自互聯網上各種博客文章和資源的拼拼湊湊,沒有真正一致或明確的最佳實踐,而是通過自然而然隨意的選擇。我想針對我最終得到的成果提供一些文檔,以幫助那些也許還在坑裡面掙扎的其他人,畢竟他們只是想要編寫代碼而已,而非不得不去了解Angular和Jasmine中所有的怪異特性和獨特用法

閱讀全文

與angularjs控制器初始化相關的資料

熱點內容
wordpress製作單頁網站導航頁面 瀏覽:277
什麼海外網站可以看限製片 瀏覽:596
指尖見app在哪裡下載 瀏覽:367
java聊天室課程設計 瀏覽:670
responsejavascript 瀏覽:71
如何從殺毒軟體裡面恢復出文件 瀏覽:972
越獄iphone如何備份 瀏覽:124
蘋果四S萬能鑰匙怎麼破不開 瀏覽:603
網路列印機共享怎麼連接 瀏覽:313
fme系統找不到指定文件 瀏覽:301
iphoneid和密碼忘了怎麼辦 瀏覽:238
蘋果電腦優盤里的文件如何加密 瀏覽:284
word標題名和文件名一致 瀏覽:957
excel修改後的文件保持了怎麼恢復 瀏覽:340
社保網路認證怎麼弄 瀏覽:92
蘋果手機怎麼傳數據到新手機相冊 瀏覽:50
5s升級ios92無服務 瀏覽:354
ubuntu翻譯工具 瀏覽:665
wifi安裝教程 瀏覽:398
蘋果有些qq文件打不開 瀏覽:139

友情鏈接