Angular學(xué)習(xí)筆記(1)—初識AngularJS

AngularJS是什么

AngularJS的官方文檔這樣介紹它:

完全使用JavaScript編寫的客戶端技術(shù)颈渊。同其它歷史悠久的Web技術(shù)(HTML夹界、CSS赌莺、JavaScript)配合使用窖逗,使Web應(yīng)用開發(fā)比以往更簡單累奈、更快捷斥铺。

AngularJS的開發(fā)團(tuán)隊(duì)將其描述為一種構(gòu)建動(dòng)態(tài)Web應(yīng)用的結(jié)構(gòu)化框架彻桃。AngularJS主要用于構(gòu)建單頁面Web應(yīng)用。
??AngularJS通過原生的Model-View-Controller(MVC晾蜘,模型-視圖-控制器)功能增強(qiáng)了HTML邻眷。利用它可以將頁面的一部分內(nèi)容封裝成一個(gè)應(yīng)用,并且不強(qiáng)迫整個(gè)頁面都使用AngularJS進(jìn)行開發(fā)剔交。

MVC(模型 視圖 控制器)

MVC背后的核心理念就是肆饶,你在你的代碼之間明確分離管理數(shù)據(jù)(模型)、應(yīng)用程序邏輯(控制器)岖常、并將數(shù)據(jù)給用戶(視圖)驯镊。
??在AngularJS應(yīng)用中,視圖層就是DOM竭鞍,控制器就是JavaScript類板惑,模型數(shù)據(jù)存儲在對象屬性中。
??視圖從模型中獲取數(shù)據(jù)展示給用戶偎快。當(dāng)用戶通過點(diǎn)擊或者輸入和應(yīng)用程序進(jìn)行交互時(shí)冯乘,控制器通過改變模型中的數(shù)據(jù)響應(yīng)。最終晒夹,模型層通知視圖層裆馒,已經(jīng)發(fā)生改變,更新顯示丐怯。

數(shù)據(jù)綁定

Hello World

第一個(gè)AngularJS例子

<body ng-app>
    <input type="text" ng-model="name">
    <h1>{{ name }}</h1>
</body>

運(yùn)行效果:


AngularJS中的數(shù)據(jù)綁定

要實(shí)現(xiàn)AngularJS的功能喷好,只要在頁面中引入angular.js,并在某個(gè)DOM元素上明確設(shè)置ng-app屬性即可读跷。ng-app屬性聲明所有被其包含的內(nèi)容都屬于這個(gè)angularJS應(yīng)用梗搅。只有被具有ng-app屬性的DOM元素包含的元素才會受AngularJS影響。
AngularJS會記錄數(shù)據(jù)模型所包含的數(shù)據(jù)在任何特定時(shí)間點(diǎn)的值效览,而不是原始值些膨。當(dāng)AngularJS認(rèn)為某個(gè)值可能發(fā)生變化時(shí),它會運(yùn)行自己的事件循環(huán)來檢查這個(gè)值是否變“臟”钦铺。如果該值從上次事件循環(huán)運(yùn)行之后發(fā)生了變化,則該值被認(rèn)為是“臟”值肢预。這個(gè)過程被稱作臟檢查矛洞。臟檢查是檢查數(shù)據(jù)模型變化的有效手段。當(dāng)有潛在的變化存在時(shí),AngularJS會在事件循環(huán)時(shí)執(zhí)行臟檢查來保證數(shù)據(jù)的一致性沼本。

模塊

在AngularJS中噩峦,模塊是定義應(yīng)用的最主要方式。模塊包含了主要的應(yīng)用代碼抽兆。一個(gè)應(yīng)用可以包含多個(gè)模塊识补,每一個(gè)模塊都包含了定義具體功能的代碼。
我們使用angular.module()方法來聲明模塊辫红,這個(gè)方法接受兩個(gè)參數(shù)凭涂,第一個(gè)是模塊的名稱,第二個(gè)是依賴列表贴妻,也就是可以被注入到模塊中的對象列表切油。

angular.module('myApp', []);
//這個(gè)方法相當(dāng)于AngularJS模塊的setter方法,是用來定義模塊的名惩。

調(diào)用這個(gè)方法時(shí)如果只傳遞一個(gè)參數(shù)澎胡,就可以用它來引用模塊。

// 這個(gè)方法用于獲取應(yīng)用
angular.module(' myApp ')
//這個(gè)方法相當(dāng)于AngularJS模塊的getter方法娩鹉,用來獲取對模塊的引用攻谁。

接下來,就可以在angular.module('myApp')返回的對象上創(chuàng)建應(yīng)用了弯予。

參數(shù)

下面是angular.module()的參數(shù)列表戚宦。

  • name(字符串):name是模塊的名稱,字符串變量熙涤。
  • requires(字符串?dāng)?shù)組):requires包含了一個(gè)字符串變量組成的列表阁苞,每個(gè)元素都是一個(gè)模塊名稱,本模塊依賴于這些模塊祠挫,依賴需要在本模塊加載之前由注入器進(jìn)行預(yù)加載那槽。

作用域

應(yīng)用的作用域是和應(yīng)用的數(shù)據(jù)模型相關(guān)聯(lián)的,同時(shí)作用域也是表達(dá)式執(zhí)行的上下文等舔。$scope對象是定義應(yīng)用業(yè)務(wù)邏輯骚灸、控制器方法和視圖屬性的地方。
在應(yīng)用將視圖渲染并呈獻(xiàn)給用戶之前慌植,視圖中的模板會和作用域進(jìn)行連接甚牲,然后應(yīng)用會對DOM進(jìn)行設(shè)置以便將屬性變化通知給AngularJS。
作用域是應(yīng)用狀態(tài)的基礎(chǔ)蝶柿≌筛疲基于動(dòng)態(tài)綁定,我們可以依賴視圖在修改數(shù)據(jù)時(shí)立刻更新$scope交汤,也可以依賴$scope在其發(fā)生變化時(shí)立刻重新渲染視圖雏赦。
AngularJS將$scope設(shè)計(jì)成和DOM類似的結(jié)構(gòu),因此$scope可以進(jìn)行嵌套,也就是說我們可以引用父級$scope中的屬性星岗。
作用域提供了監(jiān)視數(shù)據(jù)模型變化的能力填大。它允許開發(fā)者使用其中的apply機(jī)制,將數(shù)據(jù)模型的變化在整個(gè)應(yīng)用范圍內(nèi)進(jìn)行通知俏橘。我們在作用域的上下文中定義和執(zhí)行表達(dá)式允华,同時(shí)它也是將事件通知給另一個(gè)控制器和應(yīng)用其他部分的中介。

視圖和$scope

AngularJS啟動(dòng)并生成視圖時(shí)寥掐,會將根ng-app元素同$rootScope進(jìn)行綁定靴寂。$rootScope是所有$scope對象的最上層。
$rootScope是AngularJS中最接近全局作用域的對象曹仗。在$rootScope上附加太多業(yè)務(wù)邏并不是好主意榨汤,這與污染JS的全局作用域是一樣的。
$scope對象就是一個(gè)普通的JS對象怎茫,我們可以在其上隨意修改或添加屬性收壕。
$scope對象充當(dāng)數(shù)據(jù)模型,$scope并不負(fù)責(zé)處理和操作數(shù)據(jù)轨蛤,它只是視圖和HTML之間的橋梁蜜宪。
$scope的所有屬性,都可以自動(dòng)被視圖訪問到祥山。假設(shè)我們有如下的代碼:

<div ng-app="myApp">
    <h1>Hello {{name}}</h1>
</div>

我們希望{{name}}變量是本地$scope的一個(gè)屬性圃验。

angular.module('myApp', []).run(function($rootScope) {
    $rootScope.name = "World";
});

我們可以在AngularJS應(yīng)用的模板中使用多種標(biāo)記,包括下面這些:

  • 指令:將DOM元素增強(qiáng)為可復(fù)用的DOM組件的屬性或元素
  • 值綁定:模板語法{{ }}可以將表達(dá)式綁定到視圖上
  • 過濾器:可以在視圖中使用的函數(shù)缝呕,用來進(jìn)行格式化
  • 表單控件:用來檢驗(yàn)用戶輸入的控件

作用域能做什么

作用域有以下的基本功能:

  • 提供觀察者以監(jiān)視數(shù)據(jù)模型的變化
  • 可以將數(shù)據(jù)模型的變化通知給整個(gè)應(yīng)用澳窑,甚至是系統(tǒng)外的組件
  • 可以進(jìn)行嵌套铭污,隔離業(yè)務(wù)功能和數(shù)據(jù)
  • 給表達(dá)式提供運(yùn)算時(shí)所需的執(zhí)行環(huán)境

作用域包含了渲染視圖時(shí)所需的功能和數(shù)據(jù)岗照,它是所有視圖的唯一源頭订歪±常可以將作用域理解成視圖模型(view model)。

angular.module('myApp', []).run(function($rootScope) {
    $rootScope.name = "World";
});

<div ng-app="myApp">
    <h1>Hello {{ name }}</h1>
</div>

我們可以不將變量設(shè)置在$rootScope上唉俗,而是用控制器顯式創(chuàng)建一個(gè)隔離的子$scope對象断国,把它設(shè)置到這個(gè)子對象上嗤锉。使用ng-controller指令可以將一個(gè)控制器對象附加到DOM元素上源祈,如下所示:

<div ng-app="myApp">
  <div ng-controller="MyController">
    <h1>Hello {{ name }}</h1>
  </div>
</div>

可以創(chuàng)建一個(gè)控制器來管理與其相關(guān)的變量煎源,而不用將name變量直接放在$rootScope上。

angular.module("myApp",[]).controller('MyController',function($scope) {
    $scope.name = "Ari";
});

ng-controller指令為這個(gè)DOM元素創(chuàng)建了一個(gè)新的$scope對象香缺,并將它嵌套在$rootScope中手销。

$scope的生命周期

當(dāng)AngularJS關(guān)心的事件發(fā)生在瀏覽器中時(shí),比如用戶在通過ng-model屬性監(jiān)控的輸入字段中輸入图张,或者帶有ng-click屬性的按鈕被點(diǎn)擊時(shí)原献,AngularJS的事件循環(huán)都會啟動(dòng)馏慨。這個(gè)事件將在AngularJS執(zhí)行上下文中處理。
每當(dāng)事件被處理時(shí)姑隅,$scope就會對定義的表達(dá)式求值。此時(shí)事件循環(huán)會啟動(dòng)倔撞,并且AngularJS應(yīng)用會監(jiān)控應(yīng)用程序內(nèi)的所有對象讲仰,臟值檢測循環(huán)也會運(yùn)行。
$scope對象的生命周期處理有四個(gè)不同階段痪蝇。

  • 創(chuàng)建
    在創(chuàng)建控制器或指令時(shí)鄙陡,AngularJS會用$injector創(chuàng)建一個(gè)新的作用域,并在這個(gè)新建的控制器或指令運(yùn)行時(shí)將作用域傳遞進(jìn)去躏啰。
  • 鏈接
    當(dāng)AngularJS開始運(yùn)行時(shí)趁矾,所有的$scope對象都會附加或者鏈接到視圖中。所有創(chuàng)建$scope對象的函數(shù)也會將自身附加到視圖中给僵。這些作用域?qū)援?dāng)AngularJS應(yīng)用上下文中發(fā)生變化時(shí)需要運(yùn)行的函數(shù)毫捣。這些函數(shù)被稱為$watch函數(shù),AngularJS通過這些函數(shù)獲知何時(shí)啟動(dòng)事件循環(huán)帝际。
  • 更新
    當(dāng)事件循環(huán)運(yùn)行時(shí)蔓同,它通常執(zhí)行在頂層$scope對象上(被稱作$rootScope),每個(gè)子作用域都執(zhí)行自己的臟值檢測蹲诀。每個(gè)監(jiān)控函數(shù)都會檢查變化斑粱。如果檢測到任意變化,$scope對象就會觸發(fā)指定的回調(diào)函數(shù)脯爪。
  • 銷毀
    當(dāng)一個(gè)$scope在視圖中不再需要時(shí)则北,這個(gè)作用域?qū)謇砗弯N毀自己。
    盡管永遠(yuǎn)不會需要清理作用域(因?yàn)锳ngularJS會為你處理)痕慢,但是知道是誰創(chuàng)建了這個(gè)作用域還是有用的尚揣,因?yàn)槟憧梢允褂眠@個(gè)$scope上叫做$destory()的方法來清理這個(gè)作用域。

指令和作用域

指令通常不會創(chuàng)建自己的$scope守屉,但也有例外惑艇。比如ng-controllerng-repeat指令會創(chuàng)建自己的子作用域并將它們附加到DOM元素上。

控制器

控制器的作用是增強(qiáng)視圖拇泛。在AngularJS中的控制器是一個(gè)函數(shù)滨巴,用來向視圖的作用域中添加額外的功能。我們用它來給作用域?qū)ο笤O(shè)置初始狀態(tài)俺叭,并添加自定義行為恭取。
當(dāng)我們在頁面上創(chuàng)建一個(gè)新的控制器時(shí),AngularJS會生成并傳遞一個(gè)新$scope給這個(gè)控制器熄守◎诳澹可以在這個(gè)控制器里初始化$scope耗跛。由于AngularJS會負(fù)責(zé)處理控制器的實(shí)例化過程,我們只需編寫構(gòu)造函數(shù)即可攒发。

function FirstController($scope) {
    $scope.message = "hello";
}

我們是在全局作用域中創(chuàng)建的這個(gè)函數(shù)调塌。這樣做并不合適,因?yàn)闀廴救置臻g惠猿。更合理的方式是創(chuàng)建一個(gè)模塊羔砾,然后在模塊中創(chuàng)建控制器。

var app = angular.module('app', []);
app.controller('FirstController', function($scope) {
    $scope.message = "hello";
});

只需創(chuàng)建控制器作用域中的函數(shù)偶妖,就能創(chuàng)建可以在視圖中使用的自定義操作姜凄。我們可以在視圖中像調(diào)用普通數(shù)據(jù)一樣調(diào)用$scope上的函數(shù)。
用內(nèi)置指令ng-click可以將按鈕趾访、鏈接等其他任何DOM元素同點(diǎn)擊事件進(jìn)行綁定态秧。ng-click指令將瀏覽器中的mouseup事件,同設(shè)置在DOM元素上的事件處理程序綁定在一起扼鞋。

<div ng-controller="FirstController">
    <button ng-click="add(1)" class="btn">Add</button>
    <a ng-click="subtract(1)" class="btn btn-default">Subtract</a>
    <h4>Current count: {{counter}}</h4>
</div>

按鈕和鏈接都被綁定在了內(nèi)部$scope的一個(gè)操作上申鱼,當(dāng)點(diǎn)擊任何一個(gè)元素時(shí)AngularJS都會調(diào)用相應(yīng)的方法。下面給FirstController添加一個(gè)操作:

app.controller('FirstController', function($scope) {
    $scope.counter = 0;
    $scope.add = function(amount) { $scope.counter += amount; };
    $scope.subtract = function(amount) { $scope.counter -= amount; };
});

用這種設(shè)置方式我們可以在視圖中調(diào)用add()subtract()方法藏鹊,這兩個(gè)方法可以定義在FirstController的作用域中润讥,或其父級的$scope中。
控制器可以將與一個(gè)獨(dú)立視圖相關(guān)的業(yè)務(wù)邏輯封裝在一個(gè)獨(dú)立的容器中盘寡。
控制器并不適合用來執(zhí)行DOM操作楚殿、格式化或數(shù)據(jù)操作,以及除存儲數(shù)據(jù)模型之外的狀態(tài)維護(hù)操作竿痰。它只是視圖和$scope之間的橋梁脆粥。
AngularJS允許在$scope上設(shè)置包括對象在內(nèi)的任何類型的數(shù)據(jù),并且在視圖中還可以展示對象的屬性影涉。

app.controller('MyController', function($scope) {
    $scope.person = {
        name: 'Ari Lerner'
    };
});

在擁有ng-controller='MyController'這個(gè)屬性的元素內(nèi)部的任何子元素中变隔,都可以訪問person對象,因?yàn)樗嵌x在$scope上的蟹倾。

<div ng-app="myApp">
    <div ng-controller="MyController">
        <h1>{{ person }}</h1>
        and their name:
        <h2>{{ person.name }}</h2>
    </div>
</div>

效果如圖:


正如看到的這樣匣缘,$scope對象用來從數(shù)據(jù)模型向視圖傳遞信息。同時(shí)鲜棠,它也可以用來設(shè)置事件監(jiān)聽器肌厨,同應(yīng)用的其他部分進(jìn)行交互,以及創(chuàng)建與應(yīng)用相關(guān)的特定業(yè)務(wù)邏輯豁陆。

控制器嵌套(作用域包含作用域)

AngularJS應(yīng)用的任何一個(gè)部分柑爸,無論它渲染在哪個(gè)上下文中,都有父級作用域存在盒音。對于ng-app所處的層級來講表鳍,它的父級作用域就是$rootScope馅而。有一個(gè)例外:在指令內(nèi)部創(chuàng)建的作用域被稱作孤立作用域。除了孤立作用域外譬圣,所有的作用域都通過原型繼承而來瓮恭,也就是說它們都可以訪問父級作用域。
默認(rèn)情況下胁镐,AngularJS在當(dāng)前作用域中無法找到某個(gè)屬性時(shí)偎血,便會在父級作用域中進(jìn)行查找。如果AngularJS找不到對應(yīng)的屬性盯漂,會順著父級作用域一直向上尋找,直到抵達(dá)$rootScope為止笨农。如果在$rootScope中也找不到就缆,程序會繼續(xù)運(yùn)行,但視圖無法更新谒亦。

app.controller('ParentController', function($scope) {
    $scope.person = {greeted: false};
});
app.controller('ChildController', function($scope) {
    $scope.sayHello = function() {
        $scope.person.name = 'Ari Lerner';
    };
});

如果我們將ChildController置于ParentController內(nèi)部竭宰,那ChildController$scope對象的父級作用域就是ParentController$scope對象。根據(jù)原型繼承的機(jī)制份招,我們可以在子作用域中訪問ParentController$scope對象切揭。

<div ng-controller="ParentController">
    <div ng-controller="ChildController">
        <a ng-click="sayHello()">Say hello</a>
    </div>
    {{ person }}
</div>

效果如圖:



控制器應(yīng)該盡可能保持短小精悍,而在控制器中進(jìn)行DOM操作和數(shù)據(jù)操作則是一個(gè)不好的實(shí)踐锁摔。

angular.module('myApp',[]).controller('MyController', function($scope) {
    $scope.shouldShowLogin = true;
    $scope.showLogin = function () {
        $scope.shouldShowLogin = !$scope.shouldShowLogin;
    };
    $scope.clickButton = function() {
        $('#btn span').html('Clicked');
    };
    $scope.onLogin = function(user) {
        $http({
            method: 'POST',
            url: '/login',
            data: {
                user: user
            }
        }).success(function(data) {
            // user
        });
    };
});

設(shè)計(jì)良好的應(yīng)用會將復(fù)雜的邏輯放到指令和服務(wù)中廓旬。通過使用指令和服務(wù),我們可以將控制器重構(gòu)成一個(gè)輕量且更易維護(hù)的形式谐腰。

angular.module('myApp',[]).controller('MyController',function($scope,UserSrv) {
    // 內(nèi)容可以被指令控制
    $scope.onLogin = function(user) {
        UserSrv.runLogin(user);
    };
});

表達(dá)式

{{ }}符號將一個(gè)變量綁定到$scope上的寫法本質(zhì)上就是一個(gè)表達(dá)式:{{expression}}孕豹。當(dāng)用$watch進(jìn)行監(jiān)聽時(shí),AngularJS會對表達(dá)式或函數(shù)進(jìn)行運(yùn)算十气。
表達(dá)式和eval(js)非常相似励背,但是由于表達(dá)式由AngularJS來處理,它們有以下顯著不同的特性:

  • 所有的表達(dá)式都在其所屬的作用域內(nèi)部執(zhí)行砸西,并有訪問本地$scope的權(quán)限
  • 如果表達(dá)式發(fā)生了TypeErrorReferenceError并不會拋出異常
  • 不允許使用任何流程控制功能(例如if/else
  • 可以接受過濾器和過濾器鏈

對表達(dá)式進(jìn)行的任何操作叶眉,都會在其所屬的作用域內(nèi)部執(zhí)行,因此可以在表達(dá)式內(nèi)部調(diào)用那些限制在此作用域內(nèi)的變量芹枷,并進(jìn)行循環(huán)衅疙、函數(shù)調(diào)用、將變量應(yīng)用到數(shù)學(xué)表達(dá)式中等操作杖狼。

解析AngularJS表達(dá)式

盡管AngularJS會在運(yùn)行$digest循環(huán)的過程中自動(dòng)解析表達(dá)式炼蛤,但有時(shí)手動(dòng)解析表達(dá)式也是非常有用的。AngularJS通過$parse這個(gè)內(nèi)部服務(wù)來進(jìn)行表達(dá)式的運(yùn)算蝶涩,這個(gè)服務(wù)能夠訪問當(dāng)前所處的作用域理朋。這個(gè)過程允許我們訪問定義在$scope上的原始JS數(shù)據(jù)和函數(shù)絮识。
$parse服務(wù)注入到控制器中,然后調(diào)用它就可以實(shí)現(xiàn)手動(dòng)解析表達(dá)式嗽上。```
<div ng-controller="MyController">
<input ng-model="expr" type="text" placeholder="Enter an expression" />
<h2>{{ parseValue }}</h2>
</div>

angular.module("myApp", [])
       .controller('MyController',function ($scope,$parse) {
           $scope.$watch('expr',function (newVal,oldVal,scope) {
               if (newVal !==oldVal) {
                   // 用該表達(dá)式設(shè)置parseFun
                   var parseFun = $parse(newVal);
                   // 獲取經(jīng)過解析后表達(dá)式的值
                   $scope.parsedValue = parseFun(scope);
               }
           })
       })

插值字符串

在AngularJS中次舌,我們的確有手動(dòng)運(yùn)行模板編譯的能力。例如兽愤,插值允許基于作用域上的某個(gè)條件實(shí)時(shí)更新文本字符串彼念。要在字符串模板中做插值操作,需要在對象中注入$interpolate服務(wù)浅萧。

angular.module('myApp',[])
       .controller('MyController',function($scope,$interpolate) {
           // 我們同時(shí)擁有訪問$scope和$interpolate服務(wù)的權(quán)限
       });

$interpolate服務(wù)是一個(gè)可以接受三個(gè)參數(shù)的函數(shù)逐沙,其中第一個(gè)參數(shù)是必需的。

  • text(字符串):一個(gè)包含字符插值標(biāo)記的字符串洼畅。
  • mustHaveExpression(布爾型):如果將這個(gè)參數(shù)設(shè)為true吩案,當(dāng)傳入的字符串中不含有表達(dá)式時(shí)會返回null
  • trustedContext(字符串):AngularJS會對已經(jīng)進(jìn)行過字符插值操作的字符串通過$sec.getTrusted()方法進(jìn)行嚴(yán)格的上下文轉(zhuǎn)義帝簇。

$interpolate服務(wù)返回一個(gè)函數(shù)徘郭,用來在特定的上下文中運(yùn)算表達(dá)式。
設(shè)置好這些參數(shù)后丧肴,就可以在控制器中進(jìn)行字符插值的操作了残揉。例如,假設(shè)我們希望可以在電子郵件的正文中進(jìn)行實(shí)時(shí)編輯芋浮,當(dāng)文本發(fā)生變化時(shí)進(jìn)行字符插值操作并將結(jié)果展示出來抱环。

<div ng-controller="MyController">
    <input ng-model="to" type="email" placeholder="Recipient" />
    <textarea ng-model="emailBody"></textarea>
    <pre>{{ previewText }}</pre>
</div>

由于控制器內(nèi)部設(shè)置了一個(gè)需要每次變化都重新進(jìn)行字符插值的自定義輸入字段,因此需要設(shè)置一個(gè)$watch來監(jiān)聽數(shù)據(jù)的變化途样。$watch函數(shù)會監(jiān)視$scope上的某個(gè)屬性江醇。只要屬性發(fā)生變化就會調(diào)用對應(yīng)的函數(shù)『蜗荆可以使用$watch函數(shù)在$scope上某個(gè)屬性發(fā)生變化時(shí)直接運(yùn)行一個(gè)自定義函數(shù)陶夜。

angular.module('myApp',[])
       .controller('MyController', function($scope, $interpolate) {
           // 設(shè)置監(jiān)聽
           $scope.$watch('emailBody', function(body) {
               if (body) {
                   var template = $interpolate(body);
                   $scope.previewText =template({to: $scope.to});
               }
           };
       });

現(xiàn)在,在{{previewText}}內(nèi)部的文本中可以將{{to}}當(dāng)做一個(gè)變量來使用裆站,并對文本的變化進(jìn)行實(shí)時(shí)更新条辟。如果需要在文本中使用不同于{{ }}的符號來標(biāo)識表達(dá)式的開始和結(jié)束,可以在$inter polateProvider中配置宏胯。
startSymbol()方法可以修改標(biāo)識開始的符號羽嫡。這個(gè)方法接受一個(gè)參數(shù)。

  • value(字符型):開始符號的值肩袍。

endSymbol()方法可以修改標(biāo)識結(jié)束的符號杭棵。這個(gè)方法也接受一個(gè)參數(shù)。

  • value(字符型): 結(jié)束符號的值。

如果要修改這兩個(gè)符號的設(shè)置魂爪,需要在創(chuàng)建新模塊時(shí)將$interpolateProvider注入進(jìn)去先舷。
下面我們來創(chuàng)建一個(gè)服務(wù):

angular.module('emailParser',[])
       .config(['$interpolateProvider', function($interpolateProvider) {
           $interpolateProvider.startSymbol('__');
           $interpolateProvider.endSymbol('__');
       }])
       .factory('EmailParser', ['$interpolate', function($interpolate) {
           // 處理解析的服務(wù)
           return {
               parse: function(text, context) {
                   var template = $interpolate(text);
                   return template(context);
               }
           };
       }]);

現(xiàn)在,我們已經(jīng)創(chuàng)建了一個(gè)模塊滓侍,可以將它注入到應(yīng)用中蒋川,并在郵件正文的文本中運(yùn)行這個(gè)郵件解析器:

angular.module('myApp',['emailParser'])
.controller('MyController', ['$scope', 'EmailParser',function($scope, EmailParser) {
    // 設(shè)置監(jiān)聽
    $scope.$watch('emailBody', function(body) {
        if (body) {
            $scope.previewText = EmailParser.parse(body, {
                to: $scope.to
            });
        }
    });
}]);

由于我們將表達(dá)式開始和結(jié)束的符號都設(shè)置成了__,因此需要將HTML修改成用這個(gè)符號取代{{ }}的版本撩笆。
完整代碼:

<body ng-app="myApp">
<div id="emailEditor" ng-controller="MyController">
    <input ng-model="to" type="email" placeholder="Recipient" />
    <textarea ng-model="emailBody"></textarea>
    <div id="emailPreview">
        <pre>__ previewText __</pre>
    </div>
</div>
<script>
    angular.module('myApp', ['emailParser'])
        .controller('MyController',
            ['$scope', 'EmailParser',function($scope, EmailParser) {
                $scope.to = 'ari@fullstack.io';
                $scope.emailBody = 'Hello __to__';
                // Set up a watch
                $scope.$watch('emailBody', function(body) {
                    if (body) {
                        $scope.previewText =EmailParser.parse(body, {
                            to: $scope.to
                         });
                    } 
                });
             }]);
    angular.module('emailParser', [])
        .config(['$interpolateProvider',
                function($interpolateProvider) { 
                    interpolateProvider.startSymbol('__');                    
                    $interpolateProvider.endSymbol('__');
    }])
    .factory('EmailParser', ['$interpolate', 
        function($interpolate) {
            // a service to handle parsing
            return {
                parse: function(text, context) {
                    var template = $interpolate(text);
                    return template(context);
                }
             };
    }]);
</script>
</body>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捺球,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夕冲,更是在濱河造成了極大的恐慌氮兵,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歹鱼,死亡現(xiàn)場離奇詭異胆剧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)醉冤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篙悯,“玉大人蚁阳,你說我怎么就攤上這事「胝眨” “怎么了螺捐?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長矮燎。 經(jīng)常有香客問我定血,道長,這世上最難降的妖魔是什么诞外? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任澜沟,我火速辦了婚禮,結(jié)果婚禮上峡谊,老公的妹妹穿的比我還像新娘茫虽。我一直安慰自己,他們只是感情好既们,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布濒析。 她就那樣靜靜地躺著,像睡著了一般啥纸。 火紅的嫁衣襯著肌膚如雪号杏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天斯棒,我揣著相機(jī)與錄音盾致,去河邊找鬼主经。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绰上,可吹牛的內(nèi)容都是我干的旨怠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼蜈块,長吁一口氣:“原來是場噩夢啊……” “哼鉴腻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起百揭,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤爽哎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后器一,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體课锌,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年祈秕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渺贤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡请毛,死狀恐怖志鞍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情方仿,我是刑警寧澤固棚,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站仙蚜,受9級特大地震影響此洲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜委粉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一呜师、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧艳丛,春花似錦匣掸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至戴差,卻和暖如春送爸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工袭厂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留墨吓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓纹磺,卻偏偏與公主長得像帖烘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子橄杨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

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