angular学习(一)—— 概览

来源:互联网 发布:centos的vmdk文件下载 编辑:程序博客网 时间:2024/04/30 17:56

转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/51162008

文章简述

 这篇主要通过几个小例子把angular的常用组件简单介绍一下

data binding

下面是一个简单通过quantity和costs计算Total的示例
<div ng-app ng-init="qty=1;cost=2">    <b>Invoice:</b>    <div>        Quantity: <input type="number" min="0" ng-model="qty">    </div>    <div>        Costs: <input type="number" min="0" ng-model="cost">    </div>    <div>        <b>Total:</b> {{qty * cost | currency}}    </div></div>

输出结果

输出结果

下面描述一下这段代码是如何运行的,这段代码看起来像一个带着一些新的标记的普通html文件,在angular中,这样的文件叫template,当angular运行时,它会从这个template中去解析处理这些新的标记,并且加载、转换和呈现以dom的形式。
这里写图片描述
第一种标记在angular中被称为directives,他们为一些属性或者元素增加特殊的功能,比如上面的ng-app属性,angular识别到它会自动初始化为angular应用程序。angular也为input元素增加一些扩展的功能,比如接下来的ng-model,他可以将input的值存储到一个变量中,也可以把变量的值赋予到input中,这这绑定是live的绑定,一个变化另一个随之变化,称之为双向绑定。

第二种标记是带双花括号的 {{ expression | filter }},当angular的编译器遇到这种标记时会用表达式最终的值去代替这个标记。在template中的表达式是一种类javascript的变量,angular可以对这些表达式进行读写。应该注意的是这些变量都不是全局变量,仅仅就像是javascript函数中的变量一样。angular给这些变量scope的概念,以便让他们以model的形式在文档的其他部分可以访问到。对于这个例子来说,angular对这些directives的理解就是:把两个输入框的值取出来然后相乘。

上面的例子还包含了一个filter,filter的作用主要是把表达式的值展现给用户,在这个例子中currency filter将数值最终转换为货币格式输出

页面逻辑:Controllers

让我们增加一些逻辑,可以用不同的货币输入,计算和支付这个货单。

index.html

<div ng-app="invoice1" ng-controller="InvoiceController as invoice">  <b>Invoice:</b>  <div>    Quantity: <input type="number" min="0" ng-model="invoice.qty" required >  </div>  <div>    Costs: <input type="number" min="0" ng-model="invoice.cost" required >    <select ng-model="invoice.inCurr">      <option ng-repeat="c in invoice.currencies">{{c}}</option>    </select>  </div>  <div>    <b>Total:</b>    <span ng-repeat="c in invoice.currencies">      {{invoice.total(c) | currency:c}}    </span>    <button class="btn" ng-click="invoice.pay()">Pay</button>  </div></div>

invoice1.js

angular.module('invoice1', []).controller('InvoiceController', function() {  this.qty = 1;  this.cost = 2;  this.inCurr = 'EUR';  this.currencies = ['USD', 'EUR', 'CNY'];  this.usdToForeignRates = {    USD: 1,    EUR: 0.74,    CNY: 6.09  };  this.total = function total(outCurr) {    return this.convertCurrency(this.qty * this.cost, this.inCurr, outCurr);  };  this.convertCurrency = function convertCurrency(amount, inCurr, outCurr) {    return amount * this.usdToForeignRates[outCurr] / this.usdToForeignRates[inCurr];  };  this.pay = function pay() {    window.alert("Thanks!");  };});

输出
这里写图片描述
在javascript文件中包含了一个controller,确切的说这个文件包含了一个构造器函数,创建了一个真实的controller实例。controller的作用就是将变量和函数暴露给表达式和directives。

除了一个包含controller的javascript文件外,还在html中增加了一个ng-controller directive。这个directive(InvoiceController)告诉angular它负责带该directive的元素和元素下的所有子元素。InvoiceController as invoice这个语法是告诉angular实例化InvoiceController controller并且把它保存在invoice变量在当前scope中。

我们还修改了页面所有的表达式中的变量给他们加上了invoice的前缀(controller实例)。可能会选择的货币在controller中被定义和初始化,并通过ng-repeat的方式添加到了html中。像在controller中定义total函数的那样,我们也能把{{ invoice.total(…) }}绑定到html中。

我们还给pay按钮通过ng-click directive增加了点击事件,一旦点击就会弹出一个相应的表达式。
这里写图片描述

4.业务逻辑:Services

现在,InvoiceController包含了这个示例的所有逻辑。当程序需要扩展时,有个比较好的方法是把业务逻辑从页面逻辑controller中抽取出来形成一个service,而且service也可以被其他模块复用,分层思想在angular中的一个体现。需要更改数据的话只需要在service中更改即可。

finance2.js

angular.module('finance', []).factory('currencyConverter', function() {  var currencies = ['USD', 'EUR', 'CNY'];  var usdToForeignRates = {    USD: 1,    EUR: 0.74,    CNY: 6.09  };  var convert = function (amount, inCurr, outCurr) {    return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr];  };  return {    currencies: currencies,    convert: convert  };});

invoice2.js

angular.module('invoice', ['finance']).controller('InvoiceController', ['currencyConverter', function(currencyConverter) {  this.qty = 1;  this.cost = 2;  this.inCurr = 'EUR';  this.currencies = currencyConverter.currencies;  this.total = function total(outCurr) {    return currencyConverter.convert(this.qty * this.cost, this.inCurr, outCurr);  };  this.pay = function pay() {    window.alert("Thanks!");  };}]);

首先,把convertCurrency函数和currencies数组移到finance2.js文件中,但是controller中怎么才可以访问到finance2中的函数呢?

这时Dependency Injection就派上用场了,Dependency Injection (DI)是一种软件设计模式,主要处理对象和函数的创建并且怎么样获得这些依赖,angular的一切(directives, filters, controllers, services, …)都可以被创建并且通过Dependency Injection连接。在angular中这样的DI容器叫做injector。

为了使用DI,那么就需要一个地方,所有的东西在这里被注册。在angular中,这就是modules干的事。当angular启动时,它会使用在ng-app directive定义的名字的module的配置,并且使用该module需要依赖的所有module的配置。
这里写图片描述
在上面的示例中,template包含了一个directive ng-app=”invoice”,它告诉angular用invoice作为这个应用程序的main module,代码片段angular.module(‘invoice’, [‘finance’])指明invoice module依赖于finace module,angular使用InvoiceController以及currencyConverter service。

InvoiceController怎么样才能拿到currencyConverter函数的引用呢?在angular中其实非常简单,就是在构造函数的参数中定义。injector能按照争取的顺序创建对象,并且可以把之前创建的对象传递到依赖他们的对象的构造函数中。在我妈的例子中,InvoiceController的构造函数有一个叫currencyConverter的参数。这样angularj就知道controller和service之间的依赖关系。

最后要说的是service传递函数以一个数组的方式给controller,这个数组的第一个是controller和service依赖之间约定好的一个name,第二个是service中实际使用的name,如果学过spring 应该很容易理解,这样在代码进行改动时比较容易,只需改动被依赖的代码即可,而且在javascript中也很常用,因为javascript经常被压缩,变成a. b. c. 这样的代码。




如果我的文章对您有帮助,请打赏:

2 0
原创粉丝点击