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

相关文章
相关标签/搜索