详解angularjs中的隔离作用域理解以及绑定策略

所属分类: 网络编程 / JavaScript 阅读数: 1210
收藏 0 赞 0 分享

我们首先看下面的例子:

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
  <hello></hello> 
  <hello></hello> 
  <hello></hello> 
  <hello></hello> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="IsolateScope.js"></script> 
</html> 

我们在看看IsolateScope中的代码:

var myModule = angular.module("MyModule", []); 
myModule.directive("hello", function() { 
 return { 
  restrict: 'AE', 
  template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>', 
  replace: true 
 } 
}); 

这时候当运行页面的时候发现只要有一个input中的输入变化了,这时候所有的nput的内容都会变化:

这样就会面临一个问题:我们的指令无法单独使用,于是就有了独立作用域的概念。

var myModule = angular.module("MyModule", []); 
myModule.directive("hello", function() { 
 return { 
  restrict: 'AE', 
  scope:{}, 
  template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>', 
  replace: true 
 } 
}); 

通过把scope设置为{},那么每一个指令就具有自己独立的scope空间,于是就不会相互影响了。但是angularjs中最重要的概念是:绑定策略。其具有绑定策略如下:

第一步:我们看看原始的方式,也就是不使用上面的三种绑定方式

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
 <!--控制器MyCtrl下面有指令drink,同时指令drink还有自定义的属性flavor,其值为‘百威'--> 
  <div ng-controller="MyCtrl"> 
   <drink flavor="{{ctrlFlavor}}"></drink> 
  </div> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="ScopeAt.js"></script> 
</html> 

看看ScopeAt中的内容:

var myModule = angular.module("MyModule", []); 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.ctrlFlavor="百威"; 
 //在控制器中$scope中设置了ctrlFlavor属性 
}]) 
//定义了drink指令 
myModule.directive("drink", function() { 
 return { 
  restrict:'AE', 
  template:"<div>{{flavor}}</div>" , 
   link:function(scope,element,attrs){ 
   scope.flavor=attrs.flavor; 
   //链接的时候把drink指令上的flavor属性放在scope中,然后在template中显示 
   } 
 } 
}); 

这时候的DOM结构如下:

但是,这种方式要通过attrs.flavor来获取这个指令的属性值,然后需要把这个属性值绑定到scope对象上,最后在template中才能通过{{}}这种形式获取到scope中的值!

第二步:我们使用上面的@来替换第一种方式,因为它每次都需要自己指定link函数:

var myModule = angular.module("MyModule", []); 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.ctrlFlavor="百威"; 
 //在控制器中$scope中设置了ctrlFlavor属性 
}]) 
//定义了drink指令 
myModule.directive("drink", function() { 
 return { 
  restrict:'AE', 
  scope:{ 
   flavor:'@' 
  }, 
  template:"<div>{{flavor}}</div>" 
 } 
}); 

这种方式就是把指令drink中的flavor属性值绑定到scope对象上,而且这是ng为我们自动绑定的。不过,@绑定绑定的是字符串,而不是对象!

第三步:我们来学习一下双向数据绑定

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
 <!--指定了控制器MyCtrl--> 
  <div ng-controller="MyCtrl"> 
   Ctrl: 
   <br> 
   <!--第一个输入框输入值绑定到ctrlFlavor,也就是控制器MyCtrl对应的ctrlFlavor值中--> 
   <input type="text" ng-model="ctrlFlavor"> 
   <br> 
   Directive: 
   <br> 
   <!--第二个输入框还是通过指令的方式来完成的--> 
   <drink flavor="ctrlFlavor"></drink> 
  </div> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="ScopeEqual.js"></script> 
</html> 

我们再来看看控制器中内容

var myModule = angular.module("MyModule", []); 
//指定了控制器对象 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.ctrlFlavor="百威"; 
}]) 
//指定了指令 
myModule.directive("drink", function() { 
 return { 
  restrict:'AE', 
  scope:{ 
   flavor:'=' 
   //这里通过'='指定了drink指令的flavor和scope中的双向数据绑定! 
  }, 
  template:'<input type="text" ng-model="flavor"/>' 
 } 
}); 

这就是'='这种绑定方式。其实现了双向的数据绑定策略。我们看看最后的DOM结构是怎么样的:

其实双向数据绑定<drink flavor="ctrlFlavor"></drink>是很明显的,需要好好理解双向数据绑定(指令和控制器之间的双向数据绑定)

第四步:我们使用&绑定策略来完成对controller父级方法的调用:

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
  <div ng-controller="MyCtrl"> 
  <!--接下来是三个自定义的指令greeting指令--> 
   <greeting greet="sayHello(name)"></greeting> 
   <greeting greet="sayHello(name)"></greeting> 
   <greeting greet="sayHello(name)"></greeting> 
  </div> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="ScopeAnd.js"></script> 
</html> 

其中定义了三个指令greeting,每一个指令都需要调用controller中的一个sayHello方法,(angularjs中如何实现控制器和指令之间交互指出了可以通过定义属性的方式使得控制器和指令之间进行交互,不过这里我们可以通过简单的&完成同样的功能)并且传入不同的参数name值:

var myModule = angular.module("MyModule", []); 
//为控制器指定了一个sayHello方法,同时为这个方法可以传入一个参数 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.sayHello=function(name){ 
  alert("Hello "+name); 
 } 
}]) 
myModule.directive("greeting", function() { 
 return { 
  restrict:'AE', 
  scope:{ 
   greet:'&'//传递一个来自父scope的函数用于稍后调用,获取greet参数,得到sayHello(name)函数 
  }, 
  //在template中我们在ng-click中指定一个参数,其指定方式为调用controller中greet方法,传入的参数name值为username 
  //也就是ng-model='userName'中指定的参数 
  template:'<input type="text" ng-model="userName" /><br/>'+ 
     '<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br/>' 
 } 
}); 

通过&就可以完成对父级作用方法的调用,而不是采用传统的通过为指令指定属性的方式完成控制器和指令之间的通行!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

浅谈Koa2框架利用CORS完成跨域ajax请求

这篇文章主要介绍了浅谈Koa2框架利用CORS完成跨域ajax请求,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅析Vue中method与computed的区别

在new Vue的配置参数中的computed和methods都可以处理大量的逻辑代码,但是什么时候用哪个属性,要好好区分一下才能做到正确的运用vue。这篇文章主要介绍了Vue中method与computed的区别,需要的朋友可以参考下
收藏 0 赞 0 分享

Vue2.0 http请求以及loading展示实例

下面小编就为大家分享一篇Vue2.0 http请求以及loading展示实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

轻松搞定jQuery+JSONP跨域请求的解决方案

了解了jsonp之后,大家应该也都明白了,jsonp主要就是用来实现跨域的获取数据,今天我们就来详细探讨下如何在实际中应用jsonp实现跨域
收藏 0 赞 0 分享

Vue2.0实现组件数据的双向绑定问题

这篇文章主要介绍了Vue2.0实现组件数据的双向绑定问题,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

node的process以及child_process模块学习笔记

这篇文章主要介绍了node的process以及child_process模块学习笔记,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

vue2.0 循环遍历加载不同图片的方法

下面小编就为大家分享一篇vue2.0 循环遍历加载不同图片的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈Vue2.0中v-for迭代语法的变化(key、index)

下面小编就为大家分享一篇浅谈Vue2.0中v-for迭代语法的变化(key、index),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

使用vue-aplayer插件时出现的问题的解决

这篇文章主要介绍了使用vue-aplayer插件时出现的问题的解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Element-ui table中过滤条件变更表格内容的方法

下面小编就为大家分享一篇Element-ui table中过滤条件变更表格内容的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多