99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

AngularJS 靜態(tài)模板

2022-04-15 14:32 更新

Angular模板

現(xiàn)在是時(shí)候用AngularJS制作動(dòng)態(tài)網(wǎng)頁了。我們將添加一個(gè)測(cè)試,驗(yàn)證用于控制器的代碼,我們將添加這個(gè)控制器。

為應(yīng)用程序構(gòu)造代碼有很多方式。針對(duì)Angular應(yīng)用,我們鼓勵(lì)使用模塊-視圖-控制器(MVC)設(shè)計(jì)模式以解耦代碼、分離關(guān)注點(diǎn)。考慮到這一點(diǎn),我們使用小的Angular以及JavaScript為我們的應(yīng)用添加模塊、視圖和控制器組件。

  • 現(xiàn)在下面的數(shù)據(jù)中動(dòng)態(tài)生成了三款手機(jī)的列表:

把工作空間重置到第二步

git checkout -f step-2

刷新你的瀏覽器或在線檢查這一步:Step 2 Live Demo

下面列出了第一步和第二步之間的最重要的區(qū)別。你可以在GitHub里看到完整的差異。

視圖和模板

在Angular中,視圖是模塊透過HTML模板的映射。這意味著每當(dāng)模塊有變化時(shí),Angular會(huì)刷新適當(dāng)?shù)慕壎c(diǎn),隨之更新視圖。

以下面代碼為模板,Angular結(jié)構(gòu)化了視圖組件:

app/index.html:

<html ng-app="phonecatApp">
<head>
  ...
  <script src="/attachments/image/wk/angularjs/angular.js"></script>
  <script src="/attachments/image/wk/angularjs/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">

  <ul>
    <li ng-repeat="phone in phones">
      <span>{{phone.name}}</span>
      <p>{{phone.snippet}}</p>
    </li>
  </ul>

</body>
</html>

我們用ngRepeat指令和兩個(gè)Angular表達(dá)式替代硬編碼的手機(jī)列表:

  • <li>元素標(biāo)簽上的元素屬性ng-repeat="phone in phones"是一個(gè)Angular轉(zhuǎn)發(fā)器指令。該轉(zhuǎn)發(fā)器告訴Angular為列表中的每款使用元素標(biāo)簽<li>作為模板的手機(jī)創(chuàng)建一個(gè)<li>元素。
  • 用花括號(hào)包圍的表達(dá)式({{phone.name}}{{phone.snippet}})將被替換成表達(dá)式的值。

我們已經(jīng)添加了一個(gè)新指令,稱為ng-controller,它給元素標(biāo)簽<body>附加了一個(gè)PhoneListCtrl控制器。在這個(gè)點(diǎn)上:

  • 在花括號(hào)中的表達(dá)式({{phone.name}}{{phone.snippet}})表示綁定,在我們的應(yīng)用程序模塊中參引它們,它們被設(shè)置在我們的PhoneListCtrl控制器上。
注意:我們已經(jīng)指定了一個(gè)[Angular模塊](https://docs.angularjs.org/api/ng/type/angular.Module)以載入使用`ng-app="phonecatApp"`,在那里,`phonecatApp`是我們的模塊名。該模塊將包含`PhoneListCtrl`。

模塊和控制器

數(shù)據(jù)模塊(一個(gè)簡(jiǎn)單的手機(jī)數(shù)列,以對(duì)象字面記號(hào)法表達(dá))現(xiàn)在在PhoneListCtrl控制器中實(shí)例化了。該控制器只是一個(gè)構(gòu)造器函數(shù),需要一個(gè)$scope參數(shù):

app/js/controllers.js:


var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function ($scope) {
  $scope.phones = [
    {'name': 'Nexus S',
     'snippet': 'Fast just got faster with Nexus S.'},
    {'name': 'Motorola XOOM? with Wi-Fi',
     'snippet': 'The Next, Next Generation tablet.'},
    {'name': 'MOTOROLA XOOM?',
     'snippet': 'The Next, Next Generation tablet.'}
  ];
});

在這里,我們聲明了一個(gè)控制器,稱為PhoneListCtrl,并把它注冊(cè)到一個(gè)AngularJS模塊PhonecatApp中。注意,我們的ng-app指令(在元素標(biāo)簽<html>上)現(xiàn)在指定了phonecatApp模塊名作為載入的模塊,在引導(dǎo)應(yīng)用Angular應(yīng)用程序時(shí)載入該模塊。

雖然控制器沒有做太多的事情,但是它扮演了一個(gè)至關(guān)重要的角色。通過為我們的上下文提供數(shù)據(jù)模塊,控制器允許我們?cè)谀K和視圖之間建立數(shù)據(jù)綁定。我們?cè)谡故?、?shù)據(jù)和邏輯組件之間添加點(diǎn)狀虛線,如下所示:

  • ngController指令,定位在<body>元素標(biāo)簽上,引用了我們的控制器的名稱,PhoneListCtrl(放置在JavaScript文件controllers.js上)。
  • PhoneListCtrl控件在$scope上附加了手機(jī)數(shù)據(jù),把它注入到我們的控制器函數(shù)中。該作用域根作用域的原型化的后代,在定義應(yīng)用程序的時(shí)候創(chuàng)建了該根作用域。該控制器作用域可以在元素標(biāo)簽<body ng-controller="PhoneListCtrl">內(nèi)部的所有綁定位置上可用。

作用域

一個(gè)作用域的概念在Angular中是至關(guān)重要的。作用域可以被視為膠合劑,允許模板、模塊和控制器一起工作。Angular使用作用域,以及模板、數(shù)據(jù)模塊和控制器中包含的信息,以保持模塊和視圖分離,但是同步。任何對(duì)模塊的改變會(huì)影響視圖;任何在視圖中發(fā)生的改變反應(yīng)在模塊中。

要想學(xué)習(xí)更多關(guān)于Angular作用域的知識(shí),請(qǐng)參閱angular作用域文檔

測(cè)試

從視圖中分離控制器的“Angular方法”,使測(cè)試代碼變得容易,就像是它在被開發(fā)那樣。如果你的控制器在全局命名空間中可用,則我們可以用一個(gè)模擬的scope對(duì)象簡(jiǎn)單把它實(shí)例化:

test/e2e/scenarios.js:

describe('PhoneListCtrl', function(){

  it('should create "phones" model with 3 phones', function() {
    var scope = {},
        ctrl = new PhoneListCtrl(scope);

    expect(scope.phones.length).toBe(3);
  });

});

測(cè)試實(shí)例化的PhoneListCtrl并在包含三個(gè)記錄的作用域上核查手機(jī)數(shù)列屬性。這個(gè)示例演示了為Angular中的代碼創(chuàng)建一個(gè)單元測(cè)試是多么容易。因?yàn)闇y(cè)試是軟件開發(fā)的如此至關(guān)重要的部分,我們讓在Angular中創(chuàng)建測(cè)試變得容易,從而可以鼓勵(lì)開發(fā)員編寫它們。

測(cè)試非全局控制器

在實(shí)踐中,你應(yīng)該不想讓你的控制器函數(shù)在全局命名空間內(nèi)。取而代之的是,你可以看到我們已經(jīng)利用一個(gè)phonecatApp模塊上的匿名構(gòu)造器函數(shù)注冊(cè)了控制器。

在這種情況下,Angular提供了一個(gè)服務(wù),$controller,它可以以名稱接收你的控制器。這里有使用$controller同樣的測(cè)試:

test/unit/controllersSpec.js:

describe('PhoneListCtrl', function(){

  beforeEach(module('phonecatApp'));

  it('should create "phones" model with 3 phones', inject(function($controller) {
    var scope = {},
        ctrl = $controller('PhoneListCtrl', {$scope:scope});

    expect(scope.phones.length).toBe(3);
  }));

});
  • 在每個(gè)測(cè)試開始之前,我們會(huì)告訴Angular要載入phonecatApp模塊。
  • 我們要求Angular把該$controller服務(wù)inject到我們的測(cè)試函數(shù)中。
  • 我們使用$controller以創(chuàng)建一個(gè)PhoneListCtrl的實(shí)例。
  • 利用這個(gè)實(shí)例,我們?cè)诎齻€(gè)記錄的作用域上核查了手機(jī)數(shù)列屬性。

編寫并運(yùn)行測(cè)試

Angular喜歡使用Jasmine的行為-驅(qū)動(dòng)開發(fā)(BCC)的句法。雖然Angular沒有要求你使用Jasmine,但是在這個(gè)教程中,我們用Jasmine v1.3編寫所有的測(cè)試。你可以在Jasmine官方首頁Jasmine文檔中學(xué)習(xí)Jasmine。

angular-seed項(xiàng)目是預(yù)處理的,以使用Karma運(yùn)行單元測(cè)試,但是你將需要確保已經(jīng)安裝了Karma和它的必要的插件。你可以通過運(yùn)行rpm install來做到這。

要想運(yùn)行測(cè)試,請(qǐng)運(yùn)行rpm test,然后觀察文件有什么改變。

  • Karma將自動(dòng)開始一個(gè)Chrome和Firefox瀏覽器的新實(shí)例。只需要忽略它們,讓它們?cè)诤笈_(tái)運(yùn)行。Karma將為測(cè)試執(zhí)行使用這些瀏覽器。
  • 如果你已經(jīng)在你的機(jī)器上安裝了這些瀏覽器中的一個(gè),確保在運(yùn)行測(cè)試之前更新Karma的配置文件。本地配置文件在test/karma.conf.js,然后更新browsers屬性。

    例如,如果你只安裝了Chrome:

      ...
      browsers: ['Chrome'],
      ...
    
  • 你將在終端看到以下或者類似的輸出:

      info: Karma server started at http://localhost:9876/
      info (launcher): Starting  browser "Chrome"
      info (Chrome 22.0): Connected on socket id tPUm9DXcLHtZTKbAEO-n
      Chrome 22.0: Executed 1 of 1 SUCCESS (0.093 secs / 0.004 secs)
    

    耶!測(cè)試通過了!或者沒有通過……

  • 要想重新運(yùn)行測(cè)試,只需要改變?nèi)魏卧椿蛘遲est.js文件。Karma將注意到這些改變,并將為你重新運(yùn)行測(cè)試?,F(xiàn)在是不是甜?
確保你沒有把Karma打開的瀏覽器最小化了。在一些操作系統(tǒng)中,分配到一個(gè)最小化的瀏覽器上的內(nèi)存是有限的,導(dǎo)致你的karma測(cè)試運(yùn)行變得極其緩慢。

實(shí)驗(yàn)

  • 添加對(duì)index.html的另一個(gè)綁定。例如:

    <p>Total number of phones: {{phones.length}}</p>
  • 在控制器中創(chuàng)建一個(gè)新模塊屬性,然后從模板中把它綁定到模塊上。例如:

    $scope.name = "World";

    然后向index.html添加一個(gè)新的綁定:

    <p>Hello, {{name}}!</p>

    刷新你的瀏覽器,核實(shí)它是否說了"Hello, World!"。

  • ./test/unit/controllersSpec.js中的控制器更新單元測(cè)試,以反映以前的變化。例如添加:

    expect(scope.name).toBe('World');
  • index.html中創(chuàng)建一個(gè)重復(fù)器,它結(jié)構(gòu)化了一個(gè)簡(jiǎn)單的表格:

    <table>
      <tr><th>row number</th></tr>
      <tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i}}</td></tr>
    </table>

    現(xiàn)在,讓這個(gè)基于1的列表的i在綁定中增值1。

    <table>
      <tr><th>row number</th></tr>
      <tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i+1}}</td></tr>
    </table>

    另需指出:嘗試并使一個(gè)8x8的表格使用一個(gè)額外的ng-repeat。

  • 通過把expect(scope.phones.length).toBe(3)變成toBe(4),使單元測(cè)試失敗。

總結(jié)

現(xiàn)在你有了一個(gè)動(dòng)態(tài)的應(yīng)用,功能分離開模塊、視力和控制器組件,而且你測(cè)試了它們?,F(xiàn)在,讓我們前往第三步 篩選迭代器以學(xué)習(xí)如何為應(yīng)用添加全文搜索。

    以上內(nèi)容是否對(duì)您有幫助:
    在線筆記
    App下載
    App下載

    掃描二維碼

    下載編程獅App

    公眾號(hào)
    微信公眾號(hào)

    編程獅公眾號(hào)