angularjs入门学习【应用剖析中篇】

在上一节讲完了关于应用开发中如数据绑定,添加样式一类的基础操作后,接下来,将在应用中,与控制其有关的一些事件。。。

一、UI和控制器的分离

我们需要明确控制器在应用中的三个作用:

【1】在应用模型中设置初始状态

【2】通过$scope对象向视图(UI模版)暴露函数和模型

【3】监视模型发生变化的其他部分并做出相应的动作

二、发布scope中的数据模型

传递给控制器的$scope对象是一种用来向视图暴露模型数据的机制。在我们构建的应用中可能有其他数据,但是通过scope传递这些属性时,angular只考虑模型部分。

在之前的荔枝中,我们经常看到$scope构建的数据实例,而这一过程是在控制器中完成,在这里,我们也可以通过一些间接的方法从模版建立模型。

1.使用表达式:由于表达式在可它们关联的控制器中执行,所以在表达式中设置属性和控制器中设置属性是一致的。即可以如下这么做

<button ng-click='count=3'>Set count to three</button>

其等同于

<div ng-controller='CountController'>
<button ng-click='setCount()'>Set count to three</button>
</div>

控制器定义

function CountController($scope) {
$scope.setCount = function() {
$scope.count=3;
}
}

2.通过ng-model进行一个数据绑定

三、用$watch观察模型变化

$watch(watchFn, watchAction, deepWatch)

该函数每个参数详细内容

watchFn:这个参数是angualr表达式字符串或返回监控模型的当前值的函数,该表达式会被执行多次

watchAction:这是一个函数或者表达式,当watchFn变化时将调用他们,函数形式而言,它有watchFn的新旧值,及一个$scope引用,函数前面function(newValue,oldValue,scope)

deepWatch:这是一个可选的布尔参数,如果设置成true,angualr将监视对象每个属性的变化

接下的栗子是之前购物车的升级版

<div ng-controller="CartController">
<div ng-repeat="item in items">
<span>{{item.title}}</span>
<input ng-model="item.quantity">
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
</div>
<div>Total: {{totalCart() | currency}}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>Subtotal: {{subtotal() | currency}}</div>
</div>

CartController:

function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.totalCart = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
return total;
}
$scope.subtotal = function() { return $scope.totalCart() - $scope.bill.discount;
};
function calculateDiscount(newValue, oldValue, scope) {
$scope.bill.discount = newValue > 100 ? 10 : 0;
}
$scope.$watch($scope.totalCart, calculateDiscount);
}

注意:在totalCart()建立一个监视,totalCart()用于计算该支付的总额,每当其发生变化时,watch函数就会调用calculateDiscount(),然后我们设置对这个值适当的折扣。如果总值达昱100$,就设置折扣为10$,否则为0;

上述结果

对于watch性能,我们还需要注意一些潜在的性能问题

在上述例子中,虽然其能够正常的运行,但如果我们在totoalCart()加一个调试的断电,你将会看到它被调用了六次才渲染页面,而在代码中我们很容易跟踪到三次,

1.模版中{{totalCart|currency}}

2.Subtotal()函数

3.$watch()函数

而angualr为了验证传递的模型变化已经完全传递,会再运行多一次,所以总共执行六次,而这种情况很容易造成一个循环依赖。所以我们提供了以下的集中解决办法

一种是在数组的每个元素上创建爱你$watch监控变化,不过这样只是仅仅计算了$scope属性中的total,discount,subtotal

<div>Total: {{bill.total | currency}}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>Subtotal: {{bill.subtotal | currency}}</div>

然后在控制器中,我们监视数组的元素,一旦数组发生任何变化,均会调用函数重新计算总价

function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
var calculateTotals = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalCart = total;
$scope.bill.discount = total > 100 ? 10 : 0;
$scope.bill.subtotal = total - $scope.bill.discount;
};
$scope.$watch('items', calculateTotals, true);
}

注意:在$scope指定了一个字符串的items,items将作为表达式在调用它的$scope作用域中执行

然后由于我们监视数组中的所有项,angualar不得不对它进行一份拷贝用于对比,如果遇到一个具有很多元素的列表时,可能会导致运行效率降低

所以我们可以给$watch只传一个用于重新计算属性的watchFn

$scope.$watch(function() {
var total = 0;
for (var i = 0; i < $scope.items.length; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalCart = total;
$scope.bill.discount = total > 100 ? 10 : 0;
$scope.bill.subtotal = total - $scope.bill.discount;
});

四、组织模块的注入:

函数 定义
provider(name,object OR constructor()) 可配置,有复杂逻辑的服务,可用于构造函数
factory(name,$getFunction()) 不可配置,有复杂逻辑的服务,定义一个函数,调用时返回服务实例
service(name,constructor()) 具有简单逻辑,用于创建服务实例

在这里,我们利用之前讨论过的items示例使用factory()

// Create a module to support our shopping views
var shoppingModule = angular.module('ShoppingModule', []);
// Set up the service factory to create our Items interface to the
// server-side database
shoppingModule.factory('Items', function() {
var items = {};
items.query = function() {
// In real apps, we'd pull this data from the server...
return [
{title: 'Paint pots', description: 'Pots full of paint', price: 3.95}, {title: 'Polka dots', description: 'Dots with polka’, price: 2.95},
{title: 'Pebbles', description: 'Just little rocks', price: 6.95}
];
};
return items;
});
<html ng-app='ShoppingModule'>
<body ng-controller="ShoppingController">
<h1>Shop!</h1>
<table> <tr ng-repeat=”item in items”></tr>
<td>{{item.title}}</td>
<td>{{item.description}}</td>
<td>{{item.price | currency}}</td>
</tr>
</table>
</div>

五、用过滤器过滤数据

过滤器允许你申明如何展示给用户的数据转换后插入到你的模版中。

{{ expression | filterName : parameter1 : ...parameterN }}

其中expression为任意表达式,filterName为你想用的过滤器的名称,传递给过滤器的参数用冒号隔开,

而angular有几个自带过滤器如:date,number,uppercase等,在这里就不多介绍,主要我们来学习如果自己创建一个自定义过滤器

下面例子是通过filter()函数构造一个名为titleCase的过滤器,其作用是将句子中每个单词的首字母大写

var homeModule = angular.module('HomeModule', []);
homeModule.filter('titleCase', function() {
var titleCaseFilter = function(input) {
var words = input.split(' ');
for (var i = 0; i < words.length; i++) {
words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);
}
return words.join(' ');
};
return titleCaseFilter;
});

对应的HTML模版

<body ng-app='HomeModule' ng-controller="HomeController">
<h1>{{pageHeading | titleCase}}</h1>
</body>

通过控制器赋值给模型变量

function HomeController($scope) {
$scope.pageHeading = 'behold the majesty of your page title';
}

运行结果如下图

angularjs入门学习【应用剖析中篇】

时间: 2024-11-07 20:52:32

angularjs入门学习【应用剖析中篇】的相关文章

angularjs入门学习【指令篇】

一.首先我们来了解下指令API 属性 含义 restrict 申明标识符在模版中作为元素,属性,类,注释或组合,如何使用 priority 设置模版中相对于其他标识符的执行顺序 Template 指定一个字符串式的内嵌模版,如果你指定了模版是一个URL,那么是不会使用的 tempateUrl 指定URL加载的模版,如果你已经指定了内嵌的模版字符串,那么它不会使用的 Replace 如果为真,替换当前元素,如果是假或未指定,拼接到当前元素 Transclude 移动一个标识符的原始字节带你到一个新

AngularJS入门学习笔记一

首先声明: 本博客源自于学习:跟我学AngularJs:AngularJs入门及第一个实例.通过学习,我自己的一些学习笔记. 1.AngularJS的一些基本特性 (1)使用双大括号{{}}语法进行数据绑定: (2)使用DOM控制结构来实现迭代或者隐藏DOM片段: (3)支持表单和表单的验证: (4)能将逻辑代码关联到相关的DOM元素上: (5)能将HTML分组成可重用的组件. 他是MVC结构的,有双向数据绑定的特点.下图是双向数据绑定的图解: 使用DOM作为输入,而不是字符串,是Angular

AngularJs入门学习

http://www.ituring.com.cn/article/13471 安装并配置好所有依赖环境之后,只需要在cmd进入angular-phonecat目录.接着指令操作npm start:开启服务器.如下图: 打开angular-phonecat的gitbash: 接下来就是用编译器打开angular-phonecat目录下app/index.html:进行代码编译

跟我学AngularJs:AngularJs入门及第一个实例

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:主要给大家介绍了AngularJs及其特性,并以3个实例来做说明. 下载地址:https://angularjs.org/ 一.AngualrJs简介 AngularJS是由谷歌开发出来的,它是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了.通常,我们是通过以下技术来解决静态网页技术在构建动态应用上的

AngularJS交互学习教程推荐

0.目录 目录 预览 详述 1 Learn Angular 2 AngularJS入门教程 感悟 声明 1.预览 急着赶时间,没有时间听我废话的同学,直接看今天推荐的两个AngularJS交互学习教程. CodeCademy的LearnAngularJS Fenby的AngularJS入门教程 2.详述 许多研究表明,探究式学习.游戏式学习是较为高效的学习方式,编程语言学习更是如此.正如看电影和玩游戏的区别,你在看电影的时候,你完全处于被动的.接受内容状态,而玩游戏则全然不同,你会和计算机有交互

AngularJS的学习网站及相关资源整理

学习angularjs的网站及相关资源的整理,会不断更新. angularJs的官网:https://angularjs.org/       API文档:https://docs.angularjs.org/api 官方文档很详细,感觉是学习angularjs最好的方法 angularjs入门教程:http://www.runoob.com/angularjs/angularjs-tutorial.html 英语不太好可以先看这个,可以很快看完,看完就对angularjs有一个大概的了解, 有

Angular系列----AngularJS入门教程04:迭代器过滤(转载)

我们在上一步做了很多基础性的训练,所以现在我们可以来做一些简单的事情喽.我们要加入全文检索功能(没错,这个真的非常简单!).同时,我们也会写一个端到端测试,因为一个好的端到端测试可以帮上很大忙.它监视着你的应用,并且在发生回归的时候迅速报告. 请重置工作目录: git checkout -f step-3 我们的应用现在有了一个搜索框.注意到页面上的手机列表随着用户在搜索框中的输入而变化. 步骤2和步骤3之间最重要的不同在下面列出.你可以在GitHub里看到完整的差别. 控制器 我们对控制器不做

Angular系列----AngularJS入门教程00:引导程序(转载)

我们现在开始准备编写AngularJS应用——phonecat.这一步骤(步骤0),您将会熟悉重要的源代码文件,学习启动包含AngularJS种子项目的开发环境,并在浏览器端运行应用. 进入angular-phonecat目录,运行如下命令: git checkout -f step-0 该命令将重置phonecat项目的工作目录,建议您在每一学习步骤运行此命令,将命令中的数字改成您学习步骤对应的数字,该命令将清除您在工作目录内做的任何更改. 运行以下命令: node scripts/web-s

Angular系列------AngularJS入门教程:导言和准备(转载)

学习AngularJS的一个好方法是逐步完成本教程,它将引导您构建一个完整的AngularJS web应用程序. 该web应用是一个Android设备清单的目录列表,您可以筛选列表以便查看您感兴趣的设备,然后查看设备的详细信息. 本教程将向您展示AngularJS怎样使得web应用更智能更灵活,而且不需要各种扩展程序或插件. 通过本教程的学习,您将: 阅读示例学习怎样使用AngularJS的客户端数据绑定和依赖注入功能来建立可立即响应用户操作的动态数据视图. 学习如何使用AngularJS创建数