深究AngularJS(4)——Directive和Scope数据隔离与交互

什么是隔离 Scope

AngularJS 的 directive 默认能共享父 scope 中定义的属性,例如在模版中直接使用父 scope 中的对象和属性。通常使用这种直接共享的方式可以实现一些简单的 directive 功能。当你需要创建一个可重复使用的 directive,只是偶尔需要访问或者修改父 scope 的数据,就需要使用隔离 scope。当使用隔离 scope 的时候,directive 会创建一个没有依赖父 scope 的 scope,并提供一些访问父 scope 的方式。

为什么使用隔离 Scope

当你想要写一个可重复使用的 directive,不能再依赖父 scope,这时候就需要使用隔离 scope 代替。共享 scope 可以直接共享父 scope,而隔离 scope 无法共享父scope。下图解释共享 scope 和隔离 scope 的区别:

示例可看:

共享 scope

使用共享 scope 的时候,可以直接从父 scope 中共享属性。因此下面示例可以将那么属性的值输出出来。使用的是父 scope 中定义的值。

js代码:

app.controller("myController", function ($scope) {
  $scope.name = "hello world";
}).directive("shareDirective", function () {
  return {
    template: ‘Say:{{name}}‘
  }
});

html代码

<div ng-controller="myController">
  <div share-directive=""></div>
</div>

输出结果:

Say:hello world

隔离 scope

使用隔离 scope 的时候,无法从父 scope 中共享属性。因此下面示例无法输出父 scope 中定义的 name 属性值。

js代码:

app.controller("myController", function ($scope) {
  $scope.name = "hello world";
}).directive("isolatedDirective", function () {
  return {
    scope: {},
    template: ‘Say:{{name}}‘
  }
});

html代码:

<div ng-controller="myController">
  <div isolated-directive=""></div>
</div>

输出结果:

Say:

示例请点击:http://kin-sample.coding.io/angular/directive/share-and-isolated-scope.html

从上图可以看出共享 scope 允许从父 scope 渗入到 directive 中,而隔离 scope 不能,在隔离 scope 下,给 directive 创造了一堵墙,使得父 scope 无法渗入到 directive 中。

具体文档可以参考:https://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive

如何在 directive 中创建隔离 scope

在 Directive 中创建隔离 scope 很简单,只需要定义一个 scope 属性即可,这样,这个 directive 的 scope 将会创建一个新的 scope,如果多个 directive 定义在同一个元素上,只会创建一个新的 scope。

angular.module(‘app‘).controller("myController", function ($scope) {
  $scope.user = {
    id:1,
    name:"hello world"
  };
}).directive(‘isolatedScope‘, function () {
  return {
    scope: {},
    template: ‘Name: {{user.name}} Street: {{user.addr}}‘
  };
});

现在 scope 是隔离的,user 对象将无法从父 scope 中访问,因此,在 directive 渲染的时候 user 对象的占位将不会输出内容。

隔离 scope 和父 scope 如何交互

directive 在使用隔离 scope 的时候,提供了三种方法同隔离之外的地方交互。这三种分别是

  • @ 绑定一个局部 scope 属性到当前 dom 节点的属性值。结果总是一个字符串,因为 dom 属性是字符串。
  • & 提供一种方式执行一个表达式在父 scope 的上下文中。如果没有指定 attr 名称,则属性名称为相同的本地名称。
  • = 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。

@ 局部 scope 属性

@ 方式局部属性用来访问 directive 外部环境定义的字符串值,主要是通过 directive 所在的标签属性绑定外部字符串值。这种绑定是单向的,即父 scope 的绑定变化,directive 中的 scope 的属性会同步变化,而隔离 scope 中的绑定变化,父 scope 是不知道的。

如下示例:directive 声明未隔离 scope 类型,并且使用@绑定 name 属性,在 directive 中使用 name 属性绑定父 scope 中的属性。当改变父 scope 中属性的值的时候,directive 会同步更新值,当改变 directive 的 scope 的属性值时,父 scope 无法同步更新值。

js 代码:

 app.controller("myController", function ($scope) {
   $scope.name = "hello world";
 }).directive("isolatedDirective", function () {
   return {
     scope: {
       name: "@"
     },
     template: ‘Say:{{name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="name" class="ng-pristine ng-valid">‘
   }
 });

html 代码:

<div ng-controller="myController">
   <div class="result">
     <div>
       父scope:<div>Say:{{name}}<br>改变父scope的name:<input type="text" value="" ng-model="name"/></div>
     </div>
     <div>
       隔离scope:<div isolated-directive name="{{name}}"></div>
     </div>
     <div>
       隔离scope(不使用{{name}}):<div isolated-directive name="name"></div>
     </div>
   </div>
</div>

具体演示请看:http://kin-sample.coding.io/angular/directive/isolated-scope-at-interact.html

= 局部 scope 属性

= 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。
意思是,当你想要一个双向绑定的属性的时候,你可以使用=来引入外部属性。无论是改变父 scope 还是隔离 scope 里的属性,父 scope 和隔离 scope 都会同时更新属性值,因为它们是双向绑定的关系。

示例代码:

js 代码:

 app.controller("myController", function ($scope) {
   $scope.user = {
     name: ‘hello‘,
     id: 1
   };
 }).directive("isolatedDirective", function () {
   return {
     scope: {
       user: "="
     },
     template: ‘Say:{{user.name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="user.name"/>‘
   }
 });

html 代码:

<div ng-controller="myController">
  <div>父scope:
    <div>
      Say:{{user.name}} <br> 改变父scope的name:<input type="text" value="" ng-model="user.name"/>
    </div>
  </div>
  <div>
    隔离scope:<div isolated-directive user="user"></div>
  </div>
  <div>
    隔离scope(使用{{name}}):<div isolated-directive user="{{user}}"></div>
  </div>
</div>

具体演示请看:http://kin-sample.coding.io/angular/directive/isolated-scope-eq-interact.html

& 局部 scope 属性

& 方式提供一种途经是 directive 能在父 scope 的上下文中执行一个表达式。此表达式可以是一个 function。
比如当你写了一个 directive,当用户点击按钮时,directive 想要通知 controller,controller 无法知道 directive 中发生了什么,也许你可以通过使用 angular 中的 event 广播来做到,但是必须要在 controller 中增加一个事件监听方法。
最好的方法就是让 directive 可以通过一个父 scope 中的 function,当 directive 中有什么动作需要更新到父 scope 中的时候,可以在父 scope 上下文中执行一段代码或者一个函数。

如下示例在 directive 中执行父 scope 的 function。

js代码:

 app.controller("myController", function ($scope) {
   $scope.value = "hello world";
   $scope.click = function () {
     $scope.value = Math.random();
   };
 }).directive("isolatedDirective", function () {
   return {
     scope: {
       action: "&"
     },
     template: ‘<input type="button" value="在directive中执行父scope定义的方法" ng-click="action()"/>‘
   }
 });

html 代码:

 <div  ng-controller="myController">
   <div>父scope:
     <div>Say:{{value}}</div>
   </div>
   <div>隔离scope:
     <div isolated-directive action="click()"></div>
   </div>
 </div>

具体演示请看:http://kin-sample.coding.io/angular/directive/isolated-scope-ad-interact.html

使用小结

在了解 directive 的隔离 scope 跟外部环境交互的三种方式之后,写一些通用性的组件更加便捷和顺手。不再担心在 directive 中改变外部环境中的值,或者执行函数的重重困境了。
更多请参考API文档:https://docs.angularjs.org/api/ng/service/$compile 。

时间: 2024-10-07 04:50:28

深究AngularJS(4)——Directive和Scope数据隔离与交互的相关文章

angularjs中directive声明scope对象时修饰符解释和用法

在angular中我们定义directive方法时,可以看到 return { restrict: 'AE', scope: {}, template: '<div></div>', link: function() {} } 除了代码中出现的属性,还有一些其他的属性可供配置,这里不作详述. 今天我们要说的重点是scope字段. 常规用法设置 scope: { name: '=', age: '=', sex: '@', say: '&' } 假设我们的hml代码如下 &l

angularjs于directive声明scope说明何时以及如何使用对象修饰符

于angular我们定义directive方法.查看 return { restrict: 'AE', scope: {}, template: '<div></div>', link: function() {} } 除了代码中出现的属性,另一些其它的属性可供配置,这里不作详述. 今天我们要说的重点是scope字段. 常规使用方法设置 scope: { name: '=', age: '=', sex: '@', say: '&' } 如果我们的hml代码例如以下 <

AngularJS Directive 隔离 Scope 数据交互

什么是隔离 Scope AngularJS 的 directive 默认能共享父 scope 中定义的属性,例如在模版中直接使用父 scope 中的对象和属性.通常使用这种直接共享的方式可以实现一些简单的 directive 功能.当你需要创建一个可重复使用的 directive,只是偶尔需要访问或者修改父 scope 的数据,就需要使用隔离 scope.当使用隔离 scope 的时候,directive 会创建一个没有依赖父 scope 的 scope,并提供一些访问父 scope 的方式.

AngularJS之directive

AngularJS是什么就不多舌了,这里简单介绍下directive.内容基本上是读书笔记,所以如果你看过<AngularJS up and running>,那么这个可以忽略. 1.在AngularJS中,directives有两个主要的类型:1??UI展示的修改器,如ng-show.ng-model2??可复用的组件,如菜单.轮播器.taps等. 2.directives定义: 1 angular.module('stockMarketApp', []) .directive('stock

【angularJS】Directive指令

AngularJS 通过被称为 指令 的新属性来扩展 HTML.指令是扩展的 HTML 属性,带有前缀 ng-. 内置指令 1.ng-app 指令初始化一个 AngularJS 应用程序. 定义了 AngularJS 应用程序的 根元素. 2.ng-init 指令初始化应用程序数据. 通常情况下,不使用 ng-init.您将使用一个控制器或模块来代替它. 3.ng-model 指令把元素值(比如输入域的值)绑定到应用程序[一般是在控制器中定义的变量]. 4.ng-repeat 指令会重复一个 H

前端angularJS利用directive实现移动端自定义软键盘的方法

最近公司项目的需求上要求我们iPad项目上一些需要输入数字的地方用我们自定义的软键盘而不是移动端设备自带的键盘,刚接到需求有点懵,因为之前没有做过,后来理了一下思路发现这东西也就那样.先看一下实现之后的效果: 实现的效果就是当点击页面中需要弹出软键盘的时候软键盘弹出,浮在页面的中间,和模态框一样的效果,可以在软键盘中输入任何数字,附带的功能有小数点.退格.清空.确定等功能.当在键盘上点击数字的时候页面中的表单中实时的添加对应的数字,上图中可以看到. 产品经理那边给的原因是iPad屏幕本来就小,如

深究angularJS系列 - 第三弹

深究angularJS系列 - 初识 深究angularJS系列 - 第二弹 深究angularJS系列 - 第三弹,我们一起深入探究angular的服务和自定义指令O(∩_∩)O~~ Angular服务 $http: $http是angular中的一个核心服务; $http利用浏览器的xmlhttprequest或JSONP与远程HTTP服务器进行交互; $http的支持多种method的请求,get.post.put.delete.jsonp等. 下面通过JSONP方法进行$http服务的使

深究angularJS系列 - 第二弹

深究angularJS系列 - 第二弹,在初步了解了Angular的基础上,进一步的针对Angular的控制器和作用域问题深入探究O(∩_∩)O~~ Angular控制器 控制器(Controller)的理解 控制器是对view的抽象,用来接收view的事件,响应view的请求: 控制器包含view的静态属性和动态的方法: 控制器与view是一对一的关系. 控制器(Controller)的结构 1 .controller("控制器的名字",function($scoppe){ 2 ..

AngularJS clone directive 指令复制

需求背景: directive模块化某表单信息,但表单信息可加入多条.此时就涉及到clone directive. 解决方式: 能够通过使用angularjs中$compile来进行clone directive.clone direcitve中常涉及到数据的绑定. 详细方法: tw.factory('DirectiveUtil', [function() { var DirectiveUtil = {}; DirectiveUtil.DirectiveBuilder = function(di