anjularjs权威教程 module 怎么清除控制器

AngularJS 教程
AngularJS 事件
AngularJS 有自己的 HTML 事件指令。
ng-click 指令
指令定义了 AngularJS 点击事件。
AngularJS 实例
&div ng-app="" ng-controller="myCtrl"&&button ng-click="count
= count + 1"&点我!&/button&
&p&{{ count }}&/p&&/div&
隐藏 HTML 元素
ng-hide 指令用于设置应用部分是否可见。
ng-hide="true" 设置 HTML 元素不可见。
ng-hide="false" 设置 HTML 元素可见。
AngularJS 实例
&div ng-app="myApp" ng-controller="personCtrl"&
&button ng-click="toggle()"&隐藏/显示&/button&
&p ng-hide="myVar"&
名: &input type="text" ng-model="firstName"&&br&
姓名: &input type="text" ng-model="lastName"&&br&&br&Full Name:
{{firstName + " " + lastName}}&/p&&/div&
&script&var app = angular.module('myApp', []);app.controller('personCtrl',
function($scope) {&&& $scope.firstName
&&&&$scope.lastName = "Doe"&&& $scope.myVar
=&&& $scope.toggle = function() {&&&&&&&
$scope.myVar = !$scope.myV&&& };});&/script&
第一部分 personController与控制器章节类似。
应用有一个默认属性: $scope.myVar
ng-hide 指令设置 &p&元素及两个输入域是否可见, 根据 myVar 的值 (true 或 false) 来设置是否可见。
toggle() 函数用于切换 myVar 变量的值(true 和 false)。
ng-hide=&true& 让元素 不可见。
显示 HTML 元素
ng-show 指令可用于设置应用中的一部分是否可见 。
ng-show=&false& 可以设置 HTML 元素
ng-show=&true& 可以以设置 HTML 元素可见。
以下实例使用了 ng-show 指令:
AngularJS 实例
&div ng-app="myApp" ng-controller="personCtrl"&
&button ng-click="toggle()"&隐藏/显示&/button&
&p ng-show="myVar"&
名: &input type="text" ng-model="firstName"&&br&
姓: &input type="text" ng-model="lastName"&&br&&br&姓名:
{{firstName + " " + lastName}}&/p&&/div&
&script&var app = angular.module('myApp', []);app.controller('personCtrl',
function($scope) {&&& $scope.firstName
= "John",&&&&$scope.lastName = "Doe"&&& $scope.myVar
=&&& $scope.toggle = function() {&&&&&&&
$scope.myVar = !$scope.myV&&& }});&/script&
3周前 (09-11)
记住登录状态
重复输入密码AngularJS Module方法详解
字体:[ ] 类型:转载 时间:
AngularJS中的Module类负责定义应用如何启动,它还可以通过声明的方式定义应用中的各个片段。我们来看看它是如何实现这些功能的
AngularJS是什么?
AngularJs(后面就简称ng了)是一个用于设计动态web应用的结构框架。首先,它是一个框架,不是类库,是像EXT一样提供一整套方案用于设计web应用。它不仅仅是一个javascript框架,因为它的核心其实是对HTML标签的增强。
何为HTML标签增强?其实就是使你能够用标签完成一部分页面逻辑,具体方式就是通过自定义标签、自定义属性等,这些HTML原生没有的标签/属性在ng中有一个名字:指令(directive)。后面会详细介绍。那么,什么又是动态web应用呢?与传统web系统相区别,web应用能为用户提供丰富的操作,能够随用户操作不断更新视图而不进行url跳转。ng官方也声明它更适用于开发CRUD应用,即数据操作比较多的应用,而非是游戏或图像处理类应用。
为了实现这些,ng引入了一些非常棒的特性,包括模板机制、数据绑定、模块、指令、依赖注入、路由。通过数据与模板的绑定,能够让我们摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。
  另外一个疑问,ng是MVC框架吗?还是MVVM框架?官网有提到ng的设计采用了MVC的基本思想,而又不完全是MVC,因为在书写代码时我们确实是在用ng-controller这个指令(起码从名字上看,是MVC吧),但这个controller处理的业务基本上都是与view进行交互,这么看来又很接近MVVM。让我们把目光移到官网那个非醒目的title上:“AngularJS — Superheroic JavaScript MVW Framework”。
AngularJS中的Module类负责定义应用如何启动,它还可以通过声明的方式定义应用中的各个片段。我们来看看它是如何实现这些功能的。
一.Main方法在哪里
&&&&&&& 如果你是从Java或者Python编程语言转过来的,那么你可能很想知道AngularJS里面的main方法在哪里?这个把所有东西启动起来,并且第一个被执行的方法在哪里?JavaScript代码里面负责实例化并且把所有东西组合到一起,然后命令应用开始运行的那个方法在哪里?
&&&&&&& 事实上,AngularJS并没有main方法,AngularJS使用模块的概念来代替main方法。模块允许我们通过声明的方式来描述应用中的依赖关系,以及如何进行组装和启动。使用这种方式的原因如下:
&&&&&&& 1.模块是声明式的。这就意味着它编写起来更加容易,同时理解起来也很容易,阅读它就像读普通的英文一样!
&&&&&&& 2.它是模块化的。这就迫使你去思考如何定义你的组件和依赖关系,让它们变得更加清晰。
&&&&&&& 3.它让测试更加容易。在单元测试吕,你可以有选择地加入模块,并且可以避免代码中存在无法进行单元测试的内容。同时,在场景测试中,你可以加载其他额外的模块,这样就可以更好地和其他组件配合使用。
&&&&&&& 例如,在我们的应用中有一个叫做"MyAwesomeApp"的模块。在HTML里面,只要把以下内容添加到&html&标签中(或者从技术上说,可以添加到任何标签中):
&html ng-app="MyAwesomeApp"&
&ng-app指令就会告诉AngularJS使用MyAwesomeApp模块来启动你的应用。那么,应该如何定义模块呢?举例来说,我们建议你为服务、指令和过滤器分别定义不同的模块。然后你的主模块可以声明依赖这些模块。
&&&&&&& 这样可以使得模块管理更加容易,因为它们都是良好的、完备的代码块,每个模块有且只有一种职能。同时,单元测试可以只加载它们所关注的模块,这样就可以减少初始化的次数,单元测试也会变得更精致、更专注。
二.加载和依赖
&&&&&&& 模块加载动作发生在两个不同的阶段,这一点从函数名上面就可以反映出来,它们分别是Config代码块和Run代码块(或者叫做阶段)。
1.Config代码块
&&&&&&& 在这一阶段里面,AngularJS会连接并注册好所有数据源。因此,只有数据源和常量可以注入到Config代码块中。那些不确定是否已经初始化好的服务不能注入进来。
2.Run代码块
&&&&&&& Run代码块用来启动你的应用,并且在注射器创建完成之后开始执行。为了避免在这一点开始之后再对系统进行配置操作,只有实例和常量可以被注入到Run代码块中。你会发现,在AngularJS中,Run代码块是与main方法最类似的东西。
三.快捷方法
&&&&&&& 利用模块可以做什么呢?我们可以用它来实例化控制器、指令、过滤器以及服务,但是利用模块类还可以做更多事情。如下模块配置的API方法:
1.config(configFn)
&&&&&&& 利用此方法可以做一些注册工作,这些工作需要在模块加载时完成。
2.constant(name, object)
&&&&&&& 此方法会首先运行,所以你可以用它来声明整个应用范围内的常量,并且让它们在所有配置(config方法)和实例(后面的所有方法,例如controller、service等)方法中可用。
3.controller(name,constructor)
&&&&&&& 它的基本作用是配置好控制器方便后面使用。
4.directive(name,directiveFactory)
&&&&&&& 可以使用此方法在应用中创建指令。
5.filter(name,filterFactory)
&&&&&&& 允许你创建命名的AngularJS过滤器,就像前面章节所讨论的那样。
6.run(initializationFn)
&&&&&&& 如果你想要在注射器启动之后执行某些操作,而这些操作需要在页面对用户可用之前执行,就可以使用此方法。
7.value(name,object)
&&&&&&& 允许在整个应用中注射值。
8.factory(name,factoryFn)
&&&&&&& 如果你有一个类或者对象,需要首先为它提供一些逻辑或者参数,然后才能对它初始化,那么你就可以使用这里的factory接口。factory是一个函数,它负责创建一些特定的值(或者对象)。我们来看一个greeter(打招呼)函数的实例,这个函数需要一条问候语来初始化:
function Greeter(salutation) {
this.greet = function(name) {
return salutation + ' ' +
&greeter函数示例如下:
myApp.factory('greeter', function(salut) {
return new Greeter(salut);
&然后可以这样来调用它:
var myGreeter = greeter('Halo');
9.service(name,object)
&&&&&&& factory和service之间的不同点在于,factory会直接调用传递给它的函数,然后返回执行的结果;而service将会使用"new"关键字来调用传递给它的构造方法,然后再返回结果。所以,前面的greeter Factory可以替换成下面这个greeter Service:
myApp.service('greeter', Greeter);
&每当我们需要一个greeter实例的时候,AngularJS就会调用新的Greeter()来返回一个实例。
10.provider(name,providerFn)
&&&&&&& provider是这几个方法中最复杂的部分(显然,也是可配置性最好的部分)。provider中既绑定了factory也绑定了service,并且在注入系统准备完毕之前,还可以享受到配置provider函数的好处(也就是config块)。
&&&&&&& 我们来看看使用provider改造之后的greeter Service是什么样子:
myApp.provider('greeter', function() {
var salutation = 'Hello';
this.setSalutation = function(s) {
salutation =
function Greeter(a) {
this.greet = function() {
return salutation + ' ' +
this.$get = function(a) {
return new Greeter(a);
这样我们就可以在运行时动态设置问候语了(例如,可以根据用户使用的不同语言进行设置)。
var myApp = angular.module(myApp, []).config(function(greeterProvider) {
greeterProvider.setSalutation('Namaste');
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具11230人阅读
angular(10)
1, 利用作用域的继承方式
由于作用域的继承是基于js的原型继承方式,所以这里分为两种情况,当作用域上面的值为基本类型的时候,修改父作用域上面的值会 影响到子作用域,反之,修改子作用域只会影响子作用域的值,不会影响父作用域上面的值;如果需要父作用域与子作用域共享一个值 的话,就需要用到后面一种,即作用域上的值为对象,任何一方的修改都能影响另一方,这是因为在js中对象都是引用类型。
function Sandcrawler($scope) {
$scope.location = &Mos Eisley North&;
$scope.move = function(newLocation) {
$scope.location = newLocation;
function Droid($scope) {
$scope.sell = function(newLocation) {
$scope.location = newLocation;
&div ng-controller=&Sandcrawler&&
&p&Location: {{location}}&/p&
&button ng-click=&move('Mos Eisley South')&&Move&/button&
&div ng-controller=&Droid&&
&p&Location: {{location}}&/p&
&button ng-click=&sell('Owen Farm')&&Sell&/button&
function Sandcrawler($scope) {
$scope.obj = {location:&Mos Eisley North&};
function Droid($scope) {
$scope.summon = function(newLocation) {
$scope.obj.location = newLocation;
&div ng-controller=&Sandcrawler&&
&p&Sandcrawler Location: {{location}}&/p&
&div ng-controller=&Droid&&
&button ng-click=&summon('Owen Farm')&&
Summon Sandcrawler
2, 基于事件的方式
在一般情况下基于继承的方式已经足够满足大部分情况了,但是这种方式没有实现兄弟控制器之间的通信方式,所以引出了事件的方式 。基于事件的方式中我们可以里面作用的$on,$emit,$boardcast这几个方式来实现,其中$on表示事件监听,$emit表示向父级以上的 作用域触发事件, $boardcast表示向子级以下的作用域广播事件。参照以下代码:
向上传播事件
function Sandcrawler($scope) {
$scope.location = &Mos Eisley North&;
$scope.$on('summon', function(e, newLocation) {
$scope.location = newLocation;
function Droid($scope) {
$scope.location = &Owen Farm&;
$scope.summon = function() {
$scope.$emit('summon', $scope.location);
&div ng-controller=&Sandcrawler&&
&p&Sandcrawler Location: {{location}}&/p&
&div ng-controller=&Droid&&
&p&Droid Location: {{location}}&/p&
&button ng-click=&summon()&&Summon Sandcrawler&/button&
向下广播事件
function Sandcrawler($scope) {
$scope.location = &Mos Eisley North&;
$scope.recall = function() {
$scope.$broadcast('recall', $scope.location);
function Droid($scope) {
$scope.location = &Owen Farm&;
$scope.$on('recall', function(e, newLocation) {
$scope.location = newLocation;
&div ng-controller=&Sandcrawler&&
&p&Sandcrawler Location: {{location}}&/p&
&button ng-click=&recall()&&Recall Droids&/button&
&div ng-controller=&Droid&&
&p&Droid Location: {{location}}&/p&
从这个用法我们可以引申出一种用于兄弟控制间进行通信的方法,首先我们一个兄弟控制中向父作用域触发一个事件,然后在父作用域 中监听事件,再广播给子作用域,这样通过事件携带的参数,实现了数据经过父作用域,在兄弟作用域之间传播。这里要注意的是,通过父元素作为中介进行传递的话,兄弟元素用的事件名不能一样,否则会进入死循环。请看代码:
兄弟作用域之间传播
function Sandcrawler($scope) {
$scope.$on('requestDroidRecall', function(e) {
$scope.$broadcast('executeDroidRecall');
function Droid($scope) {
$scope.location = &Owen Farm&;
$scope.recallAllDroids = function() {
$scope.$emit('requestDroidRecall');
$scope.$on('executeDroidRecall', function() {
$scope.location = &Sandcrawler&
&div ng-controller=&Sandcrawler&&
&div ng-controller=&Droid&&
&h2&R2-D2&/h2&
&p&Droid Location: {{location}}&/p&
&button ng-click=&recallAddDroids()&&Recall All Droids&/button&
&div ng-controller=&Droid&&
&h2&C-3PO&/h2&
&p&Droid Location: {{status}}&/p&
&button ng-click=&recallAddDroids()&&Recall All Droids&/button&
3, angular服务的方式
在ng中服务是一个单例,所以在服务中生成一个对象,该对象就可以利用依赖注入的方式在所有的控制器中共享。参照以下例子,在一个控制器修改了服务对象的值,在另一个控制器中获取到修改后的值:
var app = angular.module('myApp', []);
app.factory('instance', function(){
return {};
app.controller('MainCtrl', function($scope, instance) {
$scope.change = function() {
instance.name = $scope.test;
app.controller('sideCtrl', function($scope, instance) {
$scope.add = function() {
$scope.name = instance.name;
&div ng-controller=&MainCtrl&&
&input type=&text& ng-model=&test& /&
&div ng-click=&change()&&click me&/div&
&div ng-controller=&sideCtrl&&
&div ng-click=&add()&&my name {{name}}&/div&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:363283次
积分:2123
积分:2123
排名:第18740名
转载:61篇
评论:16条
(3)(4)(11)(7)(24)(12)(1)(4)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'AngularJs-指令和控制器交互
  前段时间我们学习了angular的指令,他通过ECMA的方式创建元素,可以让我们共用这些元素,我们也知道可以通过 link的方法给这个指令添加一些动作事件,本节,我们将写入和让angular的指令能和控制器进行交互。
1,指令和控制器的交互
&!DOCTYPE html&
&html ng-app=&MyController&&
& & &meta charset=&utf-8&&
& & &title&指令复用&/title&
& & &p ng-controller=&MyCtrl&&
& & & & &loader&滑动加载&/loader&
&script src=&js/angular-1.3.0.js&&&/script&
&script src=&js/directive-controller.js&&&/script&
上面的代码平淡无奇,有个控制器有个指令(loader),下面可以看到我们通过 directive创建了这个指令,并且我们通过link的方法给他赋值鼠标事件(mouseenter)。
var myModule = angular.module('MyController',[]);
myModule.controller('MyCtrl',function($scope){
& & $scope.loadData = function(){
& & & & console.log(&加载数据...&);
myModule.directive('loader',function(){
& & return{
& & & & restrict:'AE',
& & & & link:function(scope,element,attr){
& & & & & & element.bind('mouseenter',function(){
& & & & & & & & &scope.loadData();
& & & & & & })
我们来看看运行的结果,ok,我们打印出来 &加载数据...&。
2,多个控制器如何公用一个指令?
  我们创建指令的目的就是在于,能够复用它,当然这也是MVC的终极思想。
  我们的代码也发生了一些变化
&!DOCTYPE html&
&html ng-app=&MyController&&
& & &meta charset=&utf-8&&
& & &title&指令复用&/title&
& & &p ng-controller=&MyCtrl&&
& & & & &loader loadDataFn=&loadData()&&滑动加载&/loader&
& & &p ng-controller=&MyCtr2&&
& & & & &loader loadDataFn=&loadData2()&&滑动加载2&/loader&
&script src=&js/angular-1.3.0.js&&&/script&
&script src=&js/directive-controller.js&&&/script&
首先,我们创建了两个控制器 MyCtr1 和 MyCtr2,同时呢,我们给 loader 这个指令,加了一个自定义的属性叫 loadDataFn,给他赋的值是下面js中的两个对应控制器中的方法loadData()和loadData2();
var myModule = angular.module('MyController',[]);
myModule.controller('MyCtrl',function($scope){
& & $scope.loadData = function(){
& & & & console.log(&加载数据...&);
myModule.controller('MyCtr2',function($scope){
& & $scope.loadData2 = function(){
& & & & console.log(&加载数据2...&);
myModule.directive('loader',function(){
& & return{
& & & & restrict:'AE',
& & & & link:function(scope,element,attr){
& & & & & & element.bind('mouseenter',function(){
& & & & & & & & // scope.loadData();
& & & & & & & & // scope.$apply(&loadData()&);
& & & & & & & & scope.$apply(attr.loaddatafn);
& & & & & & })
当然,在指令的 link方法中我们也做了改变,link方法呢,给我提供了四个参数:scope、element、attr和父控制器。我们给元素绑定事件也是通过参数中的 element.bind()完成的,我们也可以通过 attr 属性获取指令上的属性,然后通过$apply的方法来完成调用就好了。在此要提交大家的是,我们在获取指令元素上的属性的时候,一定要注意,我们要把属性的名字写成小写的,这是angularJS的坑。AngularJS 指令实践指南(一) - 文章 - 伯乐在线
& AngularJS 指令实践指南(一)
指令(Directives)是所有AngularJS应用最重要的部分。尽管AngularJS已经提供了非常丰富的指令,但还是经常需要创建应用特定的指令。这篇教程会为你讲述如何自定义指令,以及介绍如何在实际项目中使用。在这篇文章的最后(第二部分),我会指导你如何使用Angular指令来创建一个简单的记事本应用。
一个指令用来引入新的HTML语法。指令是DOM元素上的标记,使元素拥有特定的行为。举例来说,静态的HTML不知道如何来创建和展现一个日期选择器控件。让HTML能识别这个语法,我们需要使用指令。指令通过某种方法来创建一个能够支持日期选择的元素。我们会循序渐进地介绍这是如何实现的。 如果你写过AngularJS的应用,那么你一定已经使用过指令,不管你有没有意识到。你肯定已经用过简单的指令,比如 ng-mode, ng-repeat, ng-show等。这些指令都赋予DOM元素特定的行为。例如,ng-repeat 重复特定的元素,ng-show 有条件地显示一个元素。如果你想让一个元素支持拖拽,你也需要创建一个指令来实现它。指令背后基本的想法很简单。它通过对元素绑定事件监听或者改变DOM而使HTML拥有真实的交互性。
jQuery视角
想象一下使用jQuery如何创建一个日期选择器。首先,我们在HTML中添加一个普通的输入框,然后通过jQuery调用 $(element).dataPicker() 来将它转变成一个日期选择器。但是,仔细想一下。当一个设计人员过来检查HTML标记的时候,他/她能否立刻猜到这个字段实际上表示的内容?这只是一个简单的输入框,或者一个日期选择器?你需要查看jQuery代码来确定这些。而Angular的方法是使用一个指令来扩展HTML。所以,一个日期选择器的指令可以是下面的形式:
&input type="text" /&
&input type="text" /&
或者是这样:
&input type="text" /&
&input type="text" /&
这种创建UI组建的方式更加直接和清晰。你可以轻易地通过查看元素就明白这到底是什么。
创建自定义指令:
一个Angular指令可以有以下的四种表现形式: 1. 一个新的HTML元素(&data-picker&&/data-picker&) 2. 元素的属性(&input type=”text” data-picker/&) 3. CSS class(&input type=”text” class=”data-picker”/&) 4. 注释(&!–directive:data-picker –&) 当然,我们可以控制我们的指令在HTML中的表现形式。下面我们来看一下AngularJS中的一个典型的指令的写法。指令注册的方式与 controller 一样,但是它返回的是一个拥有指令配置属性的简单对象(指令定义对象) 。下面的代码是一个简单的 Hello World 指令。
JavaScript
var app = angular.module('myapp', []);
app.directive('helloWorld', function() {
restrict: 'AE',
replace: 'true',
template: '&h3&Hello World!!&/h3&'
var app = angular.module('myapp', []);&app.directive('helloWorld', function() {&&return {&&&&&&restrict: 'AE',&&&&&&replace: 'true',&&&&&&template: '&h3&Hello World!!&/h3&'&&};});
在上面的代码中,app.directive()方法在模块中注册了一个新的指令。这个方法的第一个参数是这个指令的名字。第二个参数是一个返回指令定义对象的函数。如果你的指令依赖于其他的对象或者服务,比如 $rootScope, $http, 或者$compile,他们可以在这个时间被注入。这个指令在HTML中以一个元素使用,如下:
&hello-world/&
&hello:world/&
&hello-world/&//OR&hello:world/&
或者,以一个属性的方式使用:
&div hello-world&&/div&
&div hello:world/&
&div hello-world&&/div&//OR&div hello:world/&
如果你想要符合HTML5的规范,你可以在元素前面添加 x- 或者 data-的前缀。所以下面的标记也会匹配 helloWorld 指令:
&div data-hello-world&&/div&
&div x-hello-world&&/div&
<div data-hello-world></div>//OR<div x-hello-world></div>
注意: 在匹配指令的时候,Angular会在元素或者属性的名字中剔除 x- 或者 data- 前缀。 然后将 – 或者 : 连接的字符串转换成驼峰(camelCase)表现形式,然后再与注册过的指令进行匹配。这是为什么,我们在HTML中以 hello-world 的方式使用 helloWorld 指令。其实,这跟HTML对标签和属性不区分大小写有关。 尽管上面的指令仅仅实现了静态文字的显示,但是这里还是有一些有趣的点值得我们去挖掘。我们在指令定义过程中使用了三个属性来配置指令。我们来一一介绍他们的作用。
restrict – 这个属性用来指定指令在HTML中如何使用(还记得之前说的,指令的四种表示方式吗)。在上面的例子中,我们使用了 ‘AE’。所以这个指令可以被当作新的HTML元素或者属性来使用。如果要允许指令被当作class来使用,我们将 restrict 设置成 ‘AEC’。
template – 这个属性规定了指令被Angular编译和链接(link)后生成的HTML标记。这个属性值不一定要是简单的字符串。template 可以非常复杂,而且经常包含其他的指令,以及表达式({{ }})等。更多的情况下你可能会见到 templateUrl, 而不是 template。所以,理想情况下,你应该将模板放到一个特定的HTML文件中,然后将 templateUrl 属性指向它。
replace – 这个属性指明生成的HTML内容是否会替换掉定义此指令的HTML元素。在我们的例子中,我们用 &hello-world&&/hello-world&的方式使用我们的指令,并且将 replace 设置成 true。所以,在指令被编译之后,生成的模板内容替换掉了 &hello-world&&/hello-world&。最终的输出是 &h3&Hello World!!&/h3&。如果你将 replace 设置成 false,也就是默认值,那么生成的模板会被插入到定义指令的元素中。
打开这个 ,在”Hello World!!”右键检查元素内容,来更形象地明白这些。
Link函数和Scope
指令生成出的模板其实没有太多意义,除非它在特定的scope下编译。默认情况下,指令并不会创建新的子scope。更多的,它使用父scope。也就是说,如果指令存在于一个controller下,它就会使用这个controller的scope。 如何运用scope,我们要用到一个叫做 link 的函数。它由指令定义对象中的link属性配置。让我们来改变一下我们的 helloWorld 指令,当用户在一个输入框中输入一种颜色的名称时,Hello World 文字的背景色自动发生变化。同时,当用户在 Hello World 文字上点击时,背景色变回白色。 相应的HTML标记如下:
&body ng-controller="MainCtrl"&
&input type="text" ng-model="color" placeholder="Enter a color" /&
&hello-world/&
&body ng-controller="MainCtrl"&&&&input type="text" ng-model="color" placeholder="Enter a color" /&&&&hello-world/&&/body&
修改后的 helloWorld 指令如下:
JavaScript
app.directive('helloWorld', function() {
restrict: 'AE',
replace: true,
template: '&p style="background-color:{{color}}"&Hello World',
link: function(scope, elem, attrs) {
elem.bind('click', function() {
elem.css('background-color', 'white');
scope.$apply(function() {
scope.color = "white";
elem.bind('mouseover', function() {
elem.css('cursor', 'pointer');
123456789101112131415161718
app.directive('helloWorld', function() {&&return {&&&&restrict: 'AE',&&&&replace: true,&&&&template: '&p style="background-color:{{color}}"&Hello World',&&&&link: function(scope, elem, attrs) {&&&&&&elem.bind('click', function() {&&&&&&&&elem.css('background-color', 'white');&&&&&&&&scope.$apply(function() {&&&&&&&&&&scope.color = "white";&&&&&&&&});&&&&&&});&&&&&&elem.bind('mouseover', function() {&&&&&&&&elem.css('cursor', 'pointer');&&&&&&});&&&&}&&};});
我们注意到指令定义中的 link 函数。 它有三个参数:
scope – 指令的scope。在我们的例子中,指令的scope就是父controller的scope。
elem – 指令的jQLite(jQuery的子集)包装DOM元素。如果你在引入AngularJS之前引入了jQuery,那么这个元素就是jQuery元素,而不是jQLite元素。由于这个元素已经被jQuery/jQLite包装了,所以我们就在进行DOM操作的时候就不需要再使用 $()来进行包装。
attr – 一个包含了指令所在元素的属性的标准化的参数对象。举个例子,你给一个HTML元素添加了一些属性:,那么可以在 link 函数中通过 attrs.someAttribute 来使用它。
link函数主要用来为DOM元素添加事件监听、监视模型属性变化、以及更新DOM。在上面的指令代码片段中,我们添加了两个事件, click,和 mouseover。click 处理函数用来重置 &p& 的背景色,而 mouseover 处理函数改变鼠标为 pointer。在模板中有一个表达式 {{color}},当父scope中的 color 发生变化时,它用来改变 Hello World 文字的背景色。 这个
演示了这些概念。
compile函数
compile 函数在 link 函数被执行之前用来做一些DOM改造。它接收下面的参数:
tElement – 指令所在的元素
attrs – 元素上赋予的参数的标准化列表
要注意的是 compile 函数不能访问 scope,并且必须返回一个 link 函数。但是如果没有设置 compile 函数,你可以正常地配置 link 函数,(有了compile,就不能用link,link函数由compile返回)。compile函数可以写成如下的形式:
JavaScript
app.directive('test', function() {
compile: function(tElem,attrs) {
//do optional DOM transformation here
return function(scope,elem,attrs) {
//linking function here
12345678910
app.directive('test', function() {&&return {&&&&compile: function(tElem,attrs) {&&&&&&//do optional DOM transformation here&&&&&&return function(scope,elem,attrs) {&&&&&&&&//linking function here&&&&&&};&&&&}&&};});
大多数的情况下,你只需要使用 link 函数。这是因为大部分的指令只需要考虑注册事件监听、监视模型、以及更新DOM等,这些都可以在 link 函数中完成。 但是对于像 ng-repeat 之类的指令,需要克隆和重复 DOM 元素多次,在 link 函数执行之前由 compile 函数来完成。这就带来了一个问题,为什么我们需要两个分开的函数来完成生成过程,为什么不能只使用一个?要回答好这个问题,我们需要理解指令在Angular中是如何被编译的!
指令是如何被编译的
当应用引导启动的时候,Angular开始使用 $compile 服务遍历DOM元素。这个服务基于注册过的指令在标记文本中搜索指令。一旦所有的指令都被识别后,Angular执行他们的 compile 方法。如前面所讲的,compile 方法返回一个 link 函数,被添加到稍后执行的 link 函数列表中。这被称为编译阶段。如果一个指令需要被克隆很多次(比如 ng-repeat),compile函数只在编译阶段被执行一次,复制这些模板,但是link 函数会针对每个被复制的实例被执行。所以分开处理,让我们在性能上有一定的提高。这也说明了为什么在 compile 函数中不能访问到scope对象。 在编译阶段之后,就开始了链接(linking)阶段。在这个阶段,所有收集的 link 函数将被一一执行。指令创造出来的模板会在正确的scope下被解析和处理,然后返回具有事件响应的真实的DOM节点。
改变指令的Scope
默认情况下,指令获取它父节点的controller的scope。但这并不适用于所有情况。如果将父controller的scope暴露给指令,那么他们可以随意地修改 scope 的属性。在某些情况下,你的指令希望能够添加一些仅限内部使用的属性和方法。如果我们在父的scope中添加,会污染父scope。 其实我们还有两种选择:
一个子scope – 这个scope原型继承子父scope。
一个隔离的scope – 一个孤立存在不继承自父scope的scope。
这样的scope可以通过指令定义对象中 scope 属性来配置。下面的代码片段是一个例子:
JavaScript
app.directive('helloWorld', function() {
scope: true,
// use a child scope that inherits from parent
restrict: 'AE',
replace: 'true',
template: '&h3&Hello World!!&/h3&'
app.directive('helloWorld', function() {&&return {&&&&scope: true,&&// use a child scope that inherits from parent&&&&restrict: 'AE',&&&&replace: 'true',&&&&template: '&h3&Hello World!!&/h3&'&&};});
上面的代码,让Angular给指令创建一个继承自父socpe的新的子scope。 另外一个选择,隔离的scope:
JavaScript
app.directive('helloWorld', function() {
scope: {},
// use a new isolated scope
restrict: 'AE',
replace: 'true',
template: '&h3&Hello World!!&/h3&'
app.directive('helloWorld', function() {
scope: {},
// use a new isolated scope
restrict: 'AE',
replace: 'true',
template: '&h3&Hello World!!&/h3&'
这个指令使用了一个隔离的scope。隔离的scope在我们想要创建可重用的指令的时候是非常有好处的。通过使用隔离的scope,我们能够保证我们的指令是自包含的,可以被很容易的插入到HTML应用中。 它内部不能访问父的scope,所保证了父scope不被污染。 在我们的 helloWorld 指令例子中,如果我们将 scope 设置成 {},那么上面的代码将不会工作。 它会创建一个新的隔离的scope,那么相应的表达式 {{color}} 会指向到这个新的scope中,它的值将是 undefined. 使用隔离的scope并不意味着我们完全不能访问父scope的属性。其实有一些技术可以允许我们访问父scope的属性,甚至监视他们的变化。我们会在指令这个系列的第二部分中讨论这些技术,以及一些更高级的概念,比如 Controller 函数。 第二部分也会和你一起使用Angular指令创建一个较为丰富的记事本应用。 所以,请保持关注。
关于作者:
可能感兴趣的话题
还没有深入到 scope 值前缀 @ & =
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2017 伯乐在线

我要回帖

更多关于 anjular js转换按钮 的文章

 

随机推荐