angulajs 详解 directive 中 的 scope 概念
Directive 是 angularjs 中最重要的概念,我的理解就是自定义html tag, 这个自定的tag 浏览器不会解析,会有angularjs 来动态解析。
比如在html 中添加 <myPannel title="title" description="pannel description"></mypanel>, 这个myPannel tag 浏览器显然不认识,这个其实就是一个 directive. 这个directive 我们必须在js 代码中进行定义并且为其设置显示的html模板,才能让其正常在页面中显示。
本文将假设你已经知道directive 的概念,并且知道如何创建一个自定义的directive. 对于这部分内容,本文不做介绍,本文主要介绍在自定义directive 中一个非常重要的属性 scope.
在angularjs 启动的时候,会自动创建一个rootScope 对象。 创建controller和directive 的时候,会自动创建自己的私有scope对象,私有scope从rootScope继承.
Directive 中的scope
所有的directives 都有自己的 scope 对象。 在默认的情况下,directive 不会创建他们自己的scope. 他们会用他们父对象的scope作为自己的scope. 但是 angularjs 允许改变这种默认行为。
比如下面的列子:
var app = angular.module("myAPP",[]);
app.directive("mySpan",function(){
return {
restrict: "EA",
scope: true,
link: function(scope,elem,attr){ }
}
});
上面的代码我们创建一个名字为mySpan的directive. 里面有个scope 属性,我们设置值为 true. 这个属性,可以设置为下列值中的一个,true, flase 或者{}.
下面我们将接受这三个值得不同。
Directive scope 取值不同的区别
scope : false (Directives 将使用parent 的scope), 这个是默认值
看下面的列子:
1. html 代码
<div ng-app="myapp"> <div ng-controller="Ctrl1">
<h2 ng-click="changeName()">Hey {{name}}, Click me to reinit name</h2>
<div my-directive class='directive'></div>
</div>
</div>
2. Js 代码
var app = angular.module("myapp",[]); app.controller("Ctrl1",function($scope){
$scope.name = "Slardar";
$scope.changeName = function(){
$scope.name += "_";
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: false,
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name' />"
};
});
3. css
h2 {
cursor: pointer;
}
.directive {
border: 5px solid #F5BF6E;
padding: 10px;
}
预览地址: http://jsfiddle.net/od3a4ddw/9/
可以看到,在directive 里面的name 属性和controller 里面的name是一个对象。也就是说directive 使用了其parent 的scope 对象作为自己的scope对象。当在controller 中 改变name 对象的值时,directive 的name 会更新, 反之在directive 中更新name 属性,controller 里面的name 也会更新。 因为他们其实是一个对象。
scope : true(Directives 会创建一个新的scope,但是创建的这个scope 将从parent controller 中的 scope 对象继承。)
当设为false的时候,directive 会使用parent 对象的scope 对象, 设为为true 会创建一个scope 对象,但是从parent 的scope 对象继承。 这两句话,好像有点不好理解。
我们修改上面的js 代码,将scope 对象设为true
var app = angular.module("myapp",[]); app.controller("Ctrl1",function($scope){
$scope.name = "Slardar";
$scope.changeName = function(){
$scope.name +='_';
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: true,
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name' />"
};
});
预览地址: http://jsfiddle.net/od3a4ddw/10/
点击 里面的header, 可以看到在directive 里面的name 和controller 中的name 同时在改变 (也就是说在这个时候,directive 里面name 对象是从parent 对象直接获取到的(继承的原因)。但是当我们在directive 里面的textbox 输入的时候,发现对name 对象的修改不再影响 parentscope 的name 属性。 这是因为, directive 里面的name 对象是在 text box 里面的 onchange 事件后触发的创建的。也就是说directive 在text onchange 事件发生后创建了自己的name 对象。 同时在这个时候 再次点击header 发现directive 里面的name 值不再受到parent scope 中name 的影响。
Scope : {}(Directives 会创建一个新的隔离scope,这个隔离的scope 不从parent scope对象继承)
这个官方推荐的写scope 的方式, 这样就避免的directive 中的对象和parent 的对象相互影响,但是由于创建的新的隔离对象是个全新的空对象,因为为这个对象赋值就变成了一个问题。
看下面的列子:
修改js 代码如下
var app = angular.module("myapp",[]); app.controller("Ctrl1",function($scope){
$scope.name = "Slardar";
$scope.changeName = function(){
$scope.name += "-";
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: {},
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name' />"
};
});
预览地址 :http://jsfiddle.net/qggdk7gg/
从上面的列子可以看到,点击header 文字的时候,direct里面name 始终未空,这是因为directive 里面的scope 是个隔离的scope, 它对parent的scope变量一无所知。
但是我们可以通过下面的方式将值从parent 对象中传递到 directive 中。
传值有以下三种方式:
通过 @ 传值 (字符串绑定,one way binding(单向绑定),就是传递字符串到directive 进行显示),在调用directive 的时候,需要对 attribute 使用 {{}} 进行传值。
通过 = 传值 (模型 绑定, two way bingding(双向绑定)) 在调用directive 的时候,需要对 attribute 使用 模型名称 进行传值。
通过 & 传值 (方法绑定)
下面看完整的列子:
1. html 代码
<div ng-app="app"> <div class="parent" ng-controller="MainCtrl">
<div class="line">
Name inside parent scope is: <strong>{{name}}</strong>
<input type="button" ng-click="changeName()" value="Change name" />
</div>
<div class="line">
title in parent scope is: {{title}}
<input type="button" ng-click="changeTitle()" value="Change title" />
</div>
<div class="directive" my-directive
name="{{name}}"
title="title"
change-name="changeName()"
></div>
</div>
</div>
2. JS 代码
var app = angular.module("app", []); app.controller("MainCtrl", function( $scope ){
$scope.name = "Slardar";
$scope.title = "Slardar_title";
$scope.changeName = function(){
$scope.name += '_';
};
$scope.changeTitle = function(){
$scope.title += '_';
}
}); app.directive("myDirective", function(){ return {
restrict: "EA",
scope: {
name: "@",
title: "=",
changeName: "&"
},
template: [
"<div class='line'>",
"Title : <strong>{{title}}</strong>;<br/>Name : <strong>{{name}}</strong>; Change name:<input type='text' ng-model='name' /><br/>",
"</div><div class='line'>",
"<br/><input type='button' ng-click='changeName()' value='Change Name'/>"
].join("")
};
});
3. Css
.parent {
border: 20px solid #;
padding : 20px;
}
.parent,.directive {
position: relative;
}
.parent:after,.directive:after {
display: inline;
color: #fff;
font-size: normal;
position: absolute;
top:-20px;
left:-20px;
z-index: ;
padding: 1px 5px;
background-color: rgba(,,,0.5);
}
.parent:after {
content: "MainCtrl Scope";
}
.directive {
padding: 20px;
border: 20px solid #cbccdd;
margin-top: 20px;
}
.directive:after {
content: "Directive Scope"
}
.line {
border-bottom: 1px dotted #ccc;
padding: 5px ;
}
完整演示地址: http://jsfiddle.net/g5kdns5x/1/
上面可以 看以看到完整的directive 定义
<div class="directive" my-directive
name="{{name}}"
title="title"
change-name="changeName()"
></div>
其中 name 属性 用 @ 定义 单向字符串绑定,后面使用 {{}}进行赋值。 列子中 只是传递name 属性值在directive 中系那是。
title 用 = 定义 模型绑定, 后面使用 scope 中的属性名字。 列子中传递 title 模型到 directive 中, 在direct 中对title 模型进行修改会同步到parent 对象的title 中。
change-name 用 & 定义,方法绑定。后面直接跟方法调用。 例子中传递了changeName 方法到 directive 里面,使的在directive里面可以使用 parent 对象里面定义的changeName 方法。
好了,以上就是我对directive 中关于scope 定义的介绍,希望对大家的学习有所帮助。
angulajs 详解 directive 中 的 scope 概念的更多相关文章
- 转载 《AngularJS》5个实例详解Directive(指令)机制
<AngularJS>5个实例详解Directive(指令)机制 大漠穷秋 本文整理并扩展了<AngularJS>这本书第六章里面的内容,此书近期即将由电子工业出版社出版,敬请 ...
- 图文详解Unity3D中Material的Tiling和Offset是怎么回事
图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...
- java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")
http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...
- 详解Objective-C中委托和协议
Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
- 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)
用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是 ...
- (转载)详解Javascript中prototype属性(推荐)
在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...
- 详解JavaScript中的原型
前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...
- 详解Spring中Bean的作用域与生命周期
摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...
随机推荐
- android:layout_gravity和android:gravity的区别 (转)
转:http://blog.csdn.net/shakespeare001/article/details/7843460 1.首先来看看android:layout_gravity和android: ...
- 树莓派2代 B型 4核 1G内存 raspberry pi 2 model B
树莓派技术交流群:318799602 期盼已久的PI2 已经到货,Element14版,非RS版本.诚信卖家如期发货,不会像某些淘宝卖家一样,没有货还标注现货,发货时间一拖再拖. 树莓派的最新力作!! ...
- JS-JSDoc
http://usejsdoc.org/ 生成 JSDoc 格式的注释: sublime:安装 DocBlockr VSCode:自带 JSDoc 插件
- Anaconda详细安装及使用教程(带图文)
https://blog.csdn.net/ITLearnHall/article/details/81708148
- mac查看python安装路径
1.terminal : input: which Python 或者 which Python3 2.terminal: input : python --->import sys --- ...
- Redis安装笔记
到官网查找到最新版本https://redis.io/download ————————————————设置防火墙入站规则 iptables -I INPUT -p tcp –dport -j ACC ...
- LeetCode刷题笔记-递归-反转二叉树
题目描述: 翻转一棵二叉树. 解题思路: 1.对于二叉树,立马递归 2.先处理 根节点,不需改动 3.处根的左子树和右子树需要交换位置 4.递归处理左子树和右子树.步骤见1-3步 Java代码实现: ...
- LCD中6800和8080的区别【转】
8080是通过“读使能(RE)”和“写使能(WE)”两条控制线进行读写操作6800是通过“总使能(E)”和“读写选择(W/R)”两条控制线进行 很多MCU或者LCD模块外部接口一般采用并行方式,并行接 ...
- winserver 2008 找不到回收站的解决办法
桌面新建文件夹,命名为 “回收站.{645ff040-5081-101b-9f08-00aa002f954e}”,就可以了.
- CentOS7 启动docker.service失败
背景:阿里云服务器安装了docker服务,并且更改了仓库位置 需求:让docker正常启动 方法: 一.修改/etc/docker/daemon.json文件后缀 当向该文件中写入仓库配置时,该文件后 ...