Augular初探

一年多前,巧遇angular,以爲是個很是優秀的mv*框架,當時項目使用了MooTools.所以也沒繼續研究。恰好最近,同事組中有用到ng,而且要作個分享。所以就將from Why Does Angular.js Rock?javascript

從新看了遍,加之中文的翻譯有點問題,就在原有翻譯基礎上,作了點改動。順便把丟失的圖片給補充下。--last update at 20150915html

PS:斜體加粗爲新增/改動內容java

原demo的例子都在plunker上,傳送門: http://plnkr.co/users/greengerong,本身用runjs作另外一個相似的angularjs

將本身寫的本地demo上傳,demo下載web


 

http://angular-tips.com/blog/2013/08/why-does-angular-dot-js-rock/編程

慚愧,一天多年前說要完成的翻譯,最終仍是泡湯了。百度了下,發現已經有不少版本的翻譯了,轉載吧。api

angular爲何如此火

讓咱們看看下面的介紹就知道緣由了:)數組

Angular.js 是一個MV*(Model-View-Whatever,不論是MVC或者MVVM,統歸MDV(model Drive View))JavaScript框架,其是Google推出的SPA(single-page-application)應用框架,其爲咱們的web應用開發增長很多魔法變換。promise

我能夠花成天的時間告訴你爲何你必須在新項目嘗試angular.js,可是我以爲仍是百說不如一練。restful

數據綁定和scopes(做用域)

首先第一個浮出大腦的問題是:angular支持數據綁定嗎?

下面讓咱們來了解angular.js的數據綁定:

<body ng-app>
  <span>Insert your name:</span>
  <input type="text" ng-model="user.name" />
  <h3>Echo: {{user.name}}</h3>
</body>

  

在這代碼片斷中,在咱們解釋細節以前,我仍是但願嘗試下其效果:

注:此刻暫時不要太心急去了解ng-app

    如你所見,我在input中輸入的將會顯示在後邊echo。這是如何工做的?簡單來講,angular的ng-model(更多關於指令的將在文章後續)給我帶來了雙向綁定機制。

    如此是好,可是user.name存儲在哪裏呢?其存儲在咱們的$scope上,當咱們在input中輸入任何字符都會及時的更新scope對象上的user.name屬性。而後咱們能夠利用angular的表達式{{...}}現實在HTML中。因此當咱們在input中輸入時,其會及時更新scope上的user,name屬性,在由修改HTML顯示。

    好吧,這並不難,可是你所說的$scope是個什麼東東呢?在angular中$scope是鏈接controllers(控制器)和templates(模板view/視圖)的主要膠合體。咱們能夠把咱們的model存放在scope上,來達到雙向你綁定。

這就比如:



    這意味着咱們咱們從template上爲$scope設置了一個屬性對象user.name,因此咱們也能夠在controller中訪問這個對象(user.name).

讓咱們來看個更復雜的示例:

 

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

app.controller('MainCtrl', function($scope) {
  $scope.message = 'World';
});

 

  

<body ng-app="app" ng-controller="MainCtrl">
  Hello, {{ message }}
</body>

  

 

   在這裏首先咱們定義了angular application,只是簡單的建立了一個angular module,其接受一個module名字和依賴數組爲參數。

   緊接着建立了一個controller,經過調用 app module的controller方法,並傳入一個controller 名字和function。function函數接受$scope參數(能夠接受更多的參數,放在後面部分)。因此咱們能夠開始雙向綁定了。

在$scope中咱們附加了message的字符串屬性。

   在view中你可能注意到了body tag多出了一些東東,這是幹什麼的?這些是angular的指令(directives),它給HTML帶來了新的語法擴展,在這例子中咱們使用了兩個angular內置的指令:

    ng-app:它會告訴angularbody節點包含了咱們的angular應用,換句話說,在body中的一切會被angular所接受管理。其參數爲咱們的app module的名字,和咱們在javascript中命名一致。

   ng-controller:在這指令在咱們傳入的是controller 名字,此例中爲MainCtrl

  最後咱們將message插入咱們的remplate

因此其可視化表示將是:

聰明的你能夠會冒出一個疑問:咱們可以在$scope上綁定function

固然。

 

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

app.controller('MainCtrl', function($scope) {
  $scope.greet = function() {
    $scope.message = "Hello, " + $scope.user.name;
  }
});

 

 

<body ng-app="app" ng-controller="MainCtrl">
  What's your name?:
  <input type="text" ng-model="user.name" />
  <button ng-click="greet()">Click here!</button>
  <h3>{{ message }}</h3>
</body>

  

 

 

      我在示例controller中很容易瞭解到如何添加function到$scope。示例中function將修改$scope.message爲「hello ,」和從input輸入的$scope.user.name的字符串鏈接。

     而後在HTML中建立一個附加了angular bg-click 指令的button。ng-click指令是的button在被點擊時會執行咱們爲其賦值的greet()表達式。

注意:在input中enter並不會工做,這是展現ng-click如何工做。

指令

     咱們已經看見了一些指令了,指令是個什麼東東?

     指令爲HTML引入了新的語法。HTML已經很強大了,可是有時我須要更多...

看下面的例子:

<body>

<div id="chart"></div>

</body>

示例代碼在作什麼?除了看見id外,我真的什麼也不能獲知。

而後咱們只得從多餘30個javascript文件中去查找,最後咱們看見以下代碼:

$('#chart').pieChart({ ... });

Aha!原來是個餅圖(pie chart)容器。

   在這裏若是你不去查找javascript文件將沒法獲知頁面究竟是作什麼的,實現了什麼功能。

   下面咱們再來看看angular code

<body>

<pie-chart width="400" height="400" data="data"></pie-chart>

</body>

是否是語義很清晰,咱們能夠一眼看出這是一個pie chart,不只如此,並且還知道width,height,以及其數據。

   若是你對pie chart 示例感興趣,請猛擊這裏

angular內置指令

     angular給我帶來了大量的內置指令。咱們已經在前面看見了ng-app,ng-controller,ng-click,ng-model(angular的內置指令都以ng開始),接下來讓我瞭解更多的內置指令。

    有時在頁面中有部份內容咱們只但願到達某狀態(屬性爲true)才顯示:

 

<button ng-click="show = !show">Show</button>
 <div ng-show="show">
   I am only visible when show is true.
 </div>

 

  

 

ng-show僅當angular其表達式值爲true時,才顯示該元素或子元素。

注意:在這裏對於ng-click咱們並非直接在controller中建立function(此刻咱們沒真正的controller),利用angular表達式做爲指令的參數。在首次表達式爲undefined,而後咱們設置爲爲true,在false如此交替。

     angular同時也提供了ng-hide指令。

     讓咱們看些更有趣的指令,若是有個List或者數組呢?

ar app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  $scope.developers = [
      {
        name: "Jesus", country: "Spain"
      },
      {
        name: "Dave", country: "Canada"
      },
      {
        name: "Wesley", country: "USA"
      },
      {
        name: "Krzysztof", country: "Poland"
      }
    ];
});

  

<body ng-app="app" ng-controller="MainCtrl">
 <ul>
   <li ng-repeat="person in developers">
     {{person.name}} from {{person.country}}
   </li>
 </ul>
</body>

  顯示結果

Jesus from Spain
Dave from Canada
Wesley from USA
Krzysztof from Poland

棒極了,咱們在controller中定義了一個list對象,在HTML用ng-repeat就能簡單的顯示了。

   它是如何工做的?

   ng-repeat會爲集合中的每一項建立一個新的模板,在示例中有四項數據,將會重複建立下面code四次,

<li ng-repeat="person in developers">

    {{person.name}} from {{person.country}}

</li>

每次複製都會建立本身新的scope,咱們沒有爲每項手動建立scope,咱們能夠把scope理解爲其scope,可是在這裏咱們仍然可以訪問父scope

可視化的展現爲:

咱們能自定義directive

   固然,咱們能以不一樣粒度方式建立angular的directive,例如modal dialogs accordions, paginators, charts,search from ...

   angular指令老是與可視化有關?不,咱們仍然能夠建立一些非可視化的指令集。

讓咱們來看一個例子吧:

回到咱們上面的greet示例:

<body ng-app="app" ng-controller="MainCtrl">

What's your name?:

<input type="text" ng-model="user.name" />

<button ng-click="greet()">Click here!</button>

<h3>{{ message }}</h3>

</body>

  

   已經可以很好的工做了,可是咱們但願可以在頁面初始化的時候光標焦點聚焦在輸入框input。jQuery?jQuery提供了focus函數,可以很簡單的完成,可是這裏是angular教程,因此咱們須要以angular way,顯得咱們更專業些...

   同時咱們也但願咱們的HTML可以有自描述能力(譯者注:現代軟件開發特別語言語義更重要,如linq,guava,restfull...) ,因此angular directive確定是個好的選擇。

app.directive('focus', function() {

    return {

    link: function(scope, element, attrs) {

    element[0].focus();

    }

    };

});   

  

接下來,咱們能夠在能夠HTML中標註angular directive(angular directive首字母小寫駝峯命名,在前臺轉換爲全小寫-分割風格)

   directive是angular中最複雜的要點,這裏只是最簡單的directive而已,若是可能這將放在之後文章,這裏並不會深刻。

   directive須要一個object的返回對象,咱們能夠定義一些須要關注的屬性,在示例中咱們返回了一個link的連接函數(link函數主要做爲directive的行爲綁定), 咱們若是須要,也能夠替換HTML中模板。

   Link function有3個參數(準確應該是是4個)scope,節點element,還有全部HTML attribute iAttrs在link函數裏咱們能夠綁定click,mouseenter等事件,註冊指令行爲。

   在示例中咱們爲指令節點使用了focus操做。對element瞭解更多,你能夠移步到這裏

咱們能夠很簡單的使用指令以下:

 

<body ng-app="app" ng-controller="MainCtrl">

What's your name?:

<input type="text" focus ng-model="user.name" />

<button ng-click="greet()">Click here!</button>

<h3>{{ message }}</h3>

</body> 

 

  

 

目前咱們看見的directive都很簡單,如何利用指令渲染上面說的固定模板呢?

以下:

app.directive('hello', function() {

    return {

    restrict: "E",

    replace: true,

    template: "<div>Hello readers, thank you for coming</div>"

    }

});

  

 這裏返回的是帶有一些attribute的object

  • restrict:指令的使用方式

  1. Attribute 形如:<div foo></div>.

  2. Element 形如:<foo></foo>

  3. Class 形如: <div class=」foo」></div>

  4. CoMment 形如: <!-- directive: foo -->

  • replace:詢問是否是須要利用咱們的模板替換原來的節點。

  • template:咱們須要append或者replace到原節點的html模板。

 

    directive還有不少的可配置options,如編譯compile,template url ...

  在示例咱們不須要行爲的綁定,全部沒有link function。其使用以下

 

<hello></hello>

不出意外,你會發現<hello></hello>被<div>Hello readers, thank you for coming</div>所代替了

Filters(過濾器)

假想咱們有個購物車的view顯示以下:

<span>There are 13 phones in the basket. Total: {{ 1232.12 }}</span>

咱們如何利用angular表達式顯示爲貨幣格式?形如:$1,232.12

至關簡單,angular爲咱們提供了叫filter得東東,過濾器其比如unix中的管道pipeline。angular同時也內置了貨幣currency filter.

<span>There are 13 phones in the basket. Total: {{ 1232.12 | currency }}</span>

結果就變成這樣了:$1,232.12

如你所見,咱們能夠用| 使用filter,這和unix管道模型很類似。咱們也可使用|連接更多的filter

例如咱們能夠對開發人員簡單排序,在用ng-repeat顯示出來:

<ul>

    <li ng-repeat="person in developers | orderBy:'name'">

    {{ person.name }} from {{ person.country }}

    </li>

</ul>

  

按名字排序,結果以下
Dave from Canada
Jesus from Spain
Krzysztof from Poland
Wesley from USA

在這裏你發現了一些頗有趣的事?咱們能夠給filter傳遞參數!

      OrderBy filter會接受一個屬性名,並以它進行排序,示例中咱們使用 name,若是你但願反序排列,你能夠用 -name表示。

    立刻你可能會冒出你頭腦:假想咱們不止4個開發人員,有300,而且咱們但願經過 name,country過濾呢?

很是簡單:

<body ng-app="app" ng-controller="MainCtrl">

    Search: <input ng-model="search" type="text" />

    <ul>

    <li ng-repeat="person in developers | filter:search">

    {{ person.name }} from {{ person.country }}

    </li>

    </ul>

</body>

  

     在示例中請注意咱們是如何綁定search.name的,此處利用name 作filtering。filter的參數不會改變,綁定是search對象,會根據咱們在input中輸入改變,而filter則會找尋search對象中的name屬性。

    到這裏我但願你也像我同樣同樣興奮起來了!

下面咱們來自定義filter呢?實現單詞首字母大寫 filter

app.filter('capitalize', function() {

    return function(input, param) {

    return input.substring(0,1).toUpperCase()+input.substring(1);

    }

});

  

這裏咱們自定義了一個filter其接受輸入參數input和過濾器參數param的一個函數。

    接下來咱們將在view使用它:

<span>{{ "this is some text" | capitalize }}</span>

顯示結果:

This is some text

Services

   在文章最後,咱們須要再次較少下services。這是一個的維護應用程序功能邏輯部分,他是一個單間模式singleton

   爲了保持應用程序的邏輯井井有條,更趨向於將其業務邏輯放到不一樣的services,保持controller的邏輯只有流程控制和view交互邏輯。

      angular內置了不少services,如$http http請求,$q 異步promises編程模式...在這裏咱們不會討論angular的內置services,因爲有不少的services,而且很難一次性解釋完,將在後續文章。咱們將建立一個簡單的自定義services

   在controller之間共享數據對咱們頗有用,每一個controller都有本身的scope因此咱們不能將其綁定到其餘的controller。因此解決方案是services,能夠吧數據共享到services,在須要用到的地方引用它。

首先咱們來看看若是不用services,咱們將會碰見什麼問題:

<div ng-controller="MainCtrl">

    MainCtrl:

    <input type="text" ng-model="user.name">

 </div>

    <div ng-controller="SecondCtrl">

    SecondCtrl:

    <input type="text" ng-model="user.name">

</div>

  

app.controller('MainCtrl', function($scope) {

});

app.controller('SecondCtrl', function($scope) {

});

  

咱們使用了相同的ng-model,預期當一個input改變時候會及時更新到另外一個input,以下:

可是實際狀況倒是:

接下來須要藉助services來解決這個問題,利用services將user name在controller之間共享。

app.factory('UserInformation', function() {

var user = {

name: "Angular.js"

};



return user;

});

  

這裏用的是factory去建立一個service。angular中還有其餘更高級的方式去建立service,如service,provider,這將會在後續文章詳解。

這裏有不少方式去建立service,咱們選擇的是建立了一個帶有name默認值的user對象,並返回它。

在controllers中如何去使用呢?以下:

app.controller('MainCtrl', function($scope, UserInformation) {

$scope.user = UserInformation;

});



app.controller('SecondCtrl', function($scope, UserInformation) {

$scope.user = UserInformation;

});

  

如今咱們的程序形如:

酷極了,它工做了,工做了。

     如今咱們的$scope.user在MainCtrl和SecondCtrl都用的是UserInformation,而且service是單例的,因此當咱們更新其中一個controller的時候,另一個也將會被更新。也有你又有了一個疑問:UserInformation參數是從哪裏來的?

    angular核心是DI(依賴注入)在須要使用的地方會自定注入service。DI將不會在本節中講述,咱們能夠簡單的說,你建立了一個service,你能夠在module做用域的controller,directive,甚至是其餘service做爲參數來輕鬆使用。

    也許你對上面出現的$scope認爲他也是個service,其實這是一個例外,其並非真正的service注入到咱們的controller

 

中文翻譯原文:http://www.cnblogs.com/whitewolf/archive/2013/08/11/3251889.html

相關文章
相關標籤/搜索