Angular中的Sevice

說明:兩篇文章均是老外寫的文章呀潭,由高手翻譯而成,個人感覺很不錯至非,引用在此钠署。感謝原作者。

注釋:單體是一種設(shè)計(jì)模式荒椭,它限制了每一個類僅能夠?qū)嵗癁橐粋€對象谐鼎。無論我們在什么地方注入我們的service,將永遠(yuǎn)使用同一個實(shí)例趣惠。


第一篇:

幾種不同類型的Services狸棍。Angular中有幾種不同類型的services。每一種都有自己的獨(dú)特用法信卡。

Constant#

列子:

app.constant('fooConfig',{
    config1: true,
    config2: "Default config2"
});

Constant是一個非常有用的service隔缀,她經(jīng)常被用來在指令中提供默認(rèn)配置。因此如果你正在創(chuàng)建一個指令傍菇,并且你想要再給指令傳遞可選參數(shù)的同時(shí)進(jìn)行一個默認(rèn)配置猾瘸,一個Constant就是一個好辦法。

作為一個constant,我們放入其中的值將不會改變。Constant service 基本上會是一個基本類型的值或者是一個對象牵触。

value

列子:

app.value('fooConfig',{
    config1: true,
    config2: "Default config2 but it can change"
});   

一個value service有點(diǎn)像是一個constant但是它是可以被改變的淮悼。它也經(jīng)常被用在一個指令上面,來進(jìn)行配置揽思。一個value service有點(diǎn)像是一個factory service的縮小版袜腥,它經(jīng)常用來保存值但是我們不能在其中對值進(jìn)行計(jì)算。

我們可以使用angular對象的extend方法來改變一個value service:

app = angular.module("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"
});   

Factory

列子:

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是一個能狗返回任何數(shù)據(jù)類型的service羹令。對于你如何創(chuàng)建它并沒有什么可選項(xiàng),你僅僅需要在其中返回一些東西即可损痰。

正如前面所說福侈,所有的service類型都是單體,因此如果我們在一個地方修改了foo.variable卢未,其他的地方也會相應(yīng)發(fā)生改變肪凛。

Service

列子:

app.service('foo', function() {
  var thisIsPrivate = "Private";
  this.variable = "This is public";
  this.getPrivate = function() {
    return thisIsPrivate;
  };
});   

Service service 和 factory差不多。它們之間的區(qū)別在于service會接收一個構(gòu)造器辽社,因此當(dāng)你第一次使用它的時(shí)候伟墙,它將會自動運(yùn)行new

Foo()來實(shí)例化一個對象。一定要記住如果你在其他的地方也使用了這個service滴铅,它將返回同一個對象戳葵。

事實(shí)上,上面的代碼和下面的代碼等價(jià):

app.factory('foo2', function() {
  return new Foobar();
});


function Foobar() {
  var thisIsPrivate = "Private";
  this.variable = "This is public";
  this.getPrivate = function() {
    return thisIsPrivate;
  };
}   

Foobar是一個類汉匙,我們在首次使用它的時(shí)候在我們的factory中將它實(shí)例化然后將它返回譬淳。和service一樣,F(xiàn)oobar將只會實(shí)例化一次然后下次當(dāng)我們再次使用factory時(shí)它將返回同一個實(shí)例盹兢。

如果我們已經(jīng)有了一個類邻梆,并且我們想將它用在service中,我們只需要編寫如下的代碼:

app.service('foo3',Foobar);   

Provider

Provider是factory的加強(qiáng)版绎秒。事實(shí)上浦妄,上一個例子中的factory代碼等價(jià)于下面的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函數(shù)的外面,然后我們創(chuàng)建了一個setPrivate來在一個config函數(shù)中修改thisIsPrivate见芹。為什么我們需要這樣做剂娄?這難道不比在factory中添加setter要容易嗎?除此之外玄呛,還有另外一個原因阅懦。

在這里我們將thisIsPrivate移到了我們的$get函數(shù)的外面,然后我們創(chuàng)建了一個setPrivate來在一個config函數(shù)中修改thisIsPrivate徘铝。為什么我們需要這樣做耳胎?這難道不比在factory中添加setter要容易嗎惯吕?除此之外,還有另外一個原因怕午。

要注意到我們在config函數(shù)中放入的是nameProvider而不是name废登。在這里,我們實(shí)際上還是對name進(jìn)行配置郁惜。

看到這里我們其實(shí)已經(jīng)意識到了我們已經(jīng)在應(yīng)用中進(jìn)行過一些配置了堡距,像是$routeProvider以及$locationProvider,兩者分別用來配置我們的路由了HTML5模式兆蕉。

Decorator

那么現(xiàn)在已經(jīng)決定要使用前面的 foo service羽戒,但是其中還是缺少一個你想要的greet函數(shù)。你可以修改factory嗎虎韵?答案是不行半醉!但是你可以裝飾它:

app.config(function($provide){ $provide.decorator('foo',function($delegate){ $delegate.greet = function(){ return "Hello, I am a new function of 'foo'"; } });}); 

$provide是Angular用來在內(nèi)部創(chuàng)建我們的service的東西。如果我們想要使用它的話可以手動來使用它或者僅僅使用在我們的模塊中提供的函數(shù)(我們需要使用$provide來進(jìn)行裝飾)劝术。$provide有一個函數(shù),decorator呆奕,它讓我們可以裝飾我們的service养晋。它接收我們想要裝飾的service的名字并且在回調(diào)函數(shù)中接收一個$delegate來代表我們實(shí)際上的service實(shí)例。

在這里我們可以做一切我們想要的事情來裝飾我們的service梁钾。在上面的例子中绳泉,我們?yōu)槲覀冊瓉淼膕ervice添加了一個greet函數(shù)。接著我們返回了修改后的service姆泻。

經(jīng)過修改以后零酪,現(xiàn)在我們的factory中已經(jīng)有了一個叫做greet的函數(shù)。

裝飾一個service的能力是非常實(shí)用的拇勃,尤其是當(dāng)我們想要使用第三方的service時(shí)四苇,此時(shí)我們不需要將代碼復(fù)制到我們的項(xiàng)目中,而只需要進(jìn)行一些修改即可方咆。

注意:constant service不能被裝飾月腋。

創(chuàng)建一個實(shí)例

我們的services都是單體但是我們可以創(chuàng)建一個單體factory來創(chuàng)建新的實(shí)例。在你深入之前瓣赂,記住Angular中的服務(wù)都是單體并且我們不想改變這一點(diǎn)榆骚。但是,在極少數(shù)的情況下你需要生成一個新的實(shí)例煌集,你可以像下面這樣做:

//我們的類   

function Person(json){
    angular.extend(this,json);
}

Person.prototype = {
    update: function(){
        //更新內(nèi)容   
        this.name = "Dave";
        this.country = "Canada";
    }
};   

Person.getById = function(id){
    //由id來獲取一個Person的信息   
    return new Person({
        name: "Jesus",
        country: "Spain"
        });
};

//我們的factory   
app.factory('personService',function(){
    return {
        getById: Person.getById
    };
});   

在這里我們創(chuàng)建了一個Person對象妓肢,它接收一些json數(shù)據(jù)來初始化對象。然后我們在我們的原型(原型中的函數(shù)可以被Person的實(shí)例所用)中創(chuàng)建了一個函數(shù)苫纤,并且在Person上直接創(chuàng)建了一個函數(shù)(就像是類函數(shù)一樣)碉钠。

因此現(xiàn)在我們擁有了一個類函數(shù)纲缓,它將基于我們提供的id來創(chuàng)建一個新的Person對象,并且每一個對象都可以自我更新》徘眨現(xiàn)在我們僅僅需要創(chuàng)建一個能夠使用它的service色徘。

當(dāng)每次我們調(diào)用personService.getById時(shí),我們都在創(chuàng)建一個新的Person對象操禀,因此你可以在不同的控制器中使用這個service褂策,即便當(dāng)factory是一個單體,它也能生成新的對象颓屑。

總結(jié)

Service是Angular中最酷的特性之一斤寂。我們可以使用很多方法來創(chuàng)造它們,我們僅僅需要找到符合我們需求的方法然后實(shí)現(xiàn)它揪惦。

原文:鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遍搞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子器腋,更是在濱河造成了極大的恐慌溪猿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纫塌,死亡現(xiàn)場離奇詭異诊县,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)措左,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門依痊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怎披,你說我怎么就攤上這事胸嘁。” “怎么了凉逛?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵性宏,是天一觀的道長。 經(jīng)常有香客問我状飞,道長衔沼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任昔瞧,我火速辦了婚禮指蚁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘自晰。我一直安慰自己凝化,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布酬荞。 她就那樣靜靜地躺著搓劫,像睡著了一般瞧哟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枪向,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天勤揩,我揣著相機(jī)與錄音,去河邊找鬼秘蛔。 笑死陨亡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的深员。 我是一名探鬼主播负蠕,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼倦畅!你這毒婦竟也來了遮糖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤叠赐,失蹤者是張志新(化名)和其女友劉穎欲账,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芭概,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赛不,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谈山。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡宏怔,死狀恐怖奏路,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情臊诊,我是刑警寧澤鸽粉,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站抓艳,受9級特大地震影響触机,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜玷或,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一儡首、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧偏友,春花似錦蔬胯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽产场。三九已至,卻和暖如春舞竿,著一層夾襖步出監(jiān)牢的瞬間京景,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工骗奖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留确徙,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓重归,卻偏偏與公主長得像米愿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鼻吮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理育苟,服務(wù)發(fā)現(xiàn),斷路器椎木,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Angular中有幾種不同類型的services违柏。每一種都有自己的獨(dú)特用法。 需要記住的非常重要的一點(diǎn)是servi...
    TracyZhou閱讀 655評論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法香椎,類相關(guān)的語法漱竖,內(nèi)部類的語法,繼承相關(guān)的語法畜伐,異常的語法馍惹,線程的語...
    子非魚_t_閱讀 31,632評論 18 399
  • 一.constant服務(wù): app.constant("name",obj) name為服務(wù)的名字,obj為一個j...
    A你叫阿鈞閱讀 425評論 0 1
  • 1、angularjs的幾大特性是什么玛界? 雙向數(shù)據(jù)綁定万矾、依賴注入、模板慎框、指令良狈、MVC/MVVM 2、列舉幾種常見的...
    2e9a10d418ab閱讀 1,271評論 0 10