AngularJS Directive 隔离 Scope 数据交互

时间:2021-07-08 23:56:14

什么是隔离 Scope

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

为什么使用隔离 Scope

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

具体演示请看: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

AngularJS Directive 隔离 Scope 数据交互的更多相关文章

  1. AngularJs &dollar;resource 高大上的数据交互

    $resource 创建一个resource对象的工厂函数,可以让你安全的和RESFUL服务端进行数据交互. 需要注入 ngResource 模块.angular-resource[.min].js ...

  2. angularJS中directive父子组件的数据交互

    angularJS中directive父子组件的数据交互 1. 使用共享 scope 的时候,可以直接从父 scope *享属性.使用隔离 scope 的时候,无法从父 scope *享属性.在 ...

  3. angularJs中自定义directive的数据交互

    首先放官方文档地址:https://docs.angularjs.org/guide/directive 就我对directive的粗浅理解,它一般用于独立Dom元素的封装,应用场合为控件重用和逻辑模 ...

  4. AngularJS&colon; 自定义指令与控制器数据交互

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  5. AngularJS&period;directive系列:嵌套directive的通讯及scope研究

    一.directive中的scope directive无疑是AngularJS中比较复杂难懂的部分,而directive中个scope更是其中最复杂的部分了,尤其是在嵌套directive中互相通讯 ...

  6. angularjs中directive声明scope对象的用法

    总的来说用法 分三种: >1: scope: false  --> 继承父域,实现 双向数据绑定 示例代码 可自测: <!DOCTYPE html> <html lang ...

  7. AngularJS自定义指令directive:scope属性 (转载)

    原文地址:http://blog.csdn.net/VitaLemon__/article/details/52213103 一.介绍: 在AngularJS中,除了内置指令如ng-click等,我们 ...

  8. angularjs向后台传递数据,与后端进行交互

    angularjs之数据交互 function loadLeftFirstNodes (){ $http.get(sourceUrl,{ params:{ mpId: mpId, visits: ce ...

  9. 学习AngularJs&colon;Directive指令用法(完整版)

    这篇文章主要学习AngularJs:Directive指令用法,内容很全面,感兴趣的小伙伴们可以参考一下   本教程使用AngularJs版本:1.5.3 AngularJs GitHub: http ...

随机推荐

  1. Oracle 11g RAC环境下Private IP修改方法及异常处理

    Oracle 11g RAC环境下Private IP修改方法及异常处理 Oracle 11g RAC环境下Private IP修改方法及异常处理 一. 修改方法 1. 确认所有节点CRS服务以启动 ...

  2. WPF中Image的Stretch属性

    有时候我们在WPF程序中设置了图片的Width和Height,但图片显示出来的宽和高并不是我们预期的效果,这实际上是由于Image的默认Stretch属性导致的 Image的Stretch属性默认为U ...

  3. ObjectCopy

    对象的传参用的是传引用,但开发中通常不允许对传入参数进行修改.因此对象拷贝很常用,Python提供一个很方便的对象拷贝方法 如代码: __author__ = 'mengxuan' import co ...

  4. EEPlat PaaS VS Saleforce force&period;com

    综述 EEPlatPaaS和Saleforce的Force.com都是元数据驱动应用的解决方式.整体而言,Force.com提供了更上层的解决方式,屏蔽了SQL语句.数据库:EEPlat更加底层,有更 ...

  5. redis学习-散列表常用命令(hash)

    redis学习-散列表常用命令(hash)   hset,hmset:给指定散列表插入一个或者多个键值对 hget,hmget:获取指定散列表一个或者多个键值对的值 hgetall:获取所欲哦键值以及 ...

  6. 阿里云服务器创建swap分区

    阿里云服务器使用了4核8G内存配置,但最近由于jenkins构建时执行gradle打包安卓应用,导致即时的内存严重不足,线上应用长时间无法访问. 执行free命令才发现,swap分区一直是没有创建的. ...

  7. 用EventLog Analyzer的预定义报表和告警来进行Syslog管理

    用EventLog Analyzer的预定义报表和告警来进行Syslog管理 系统日志(Syslog)管理是几乎所有企业的重要需求.系统管理员将syslog看作是解决网络上系统日志支持的系统和设备性能 ...

  8. 使用nginx搭建tomcat集群配置

    软件准备: (1)jdk-8u73-linux-x64.tar.gz (2)apache-tomcat-7.0.57.tar.gz (3)nginx-1.7.7.tar.gz 准备3台Linux机器, ...

  9. Arctic Network---poj2349 最小生成树

    http://poj.org/problem?id=2349 题意:有n个点给出坐标,点和点之间可以用无线电或者卫星通信,每个点都有无线电收发器可进行无线电通信,但是只有m个点有卫星通信功能.卫星通信 ...

  10. 随机算法 - HNU 13348 Finding Lines

    Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&am ...