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时需要注意的部分,所以这一篇文章我 ...
随机推荐
- 使用vue完成一个分页效果
基于 element-ui 分页组件实现分页效果 效果如下: 使用说明: 0.首先在头部引入需要的外部文件 1.从element官方网页中复制想要的组件代码直接放入body中 2.编写逻辑代码 3.完 ...
- 探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 老板让我十分钟上手nx-admin
大体流程 参考资料: nx-admin项目地址 首先这里就不讲解vue和vuex之类的基础东西了 有兴趣的可以去官方文档了解.这里根据流程走向大概说说 路由配置 首先找到路由配置,路由配置放在了src ...
- 如何在android studio中cordova的混合开发
基于Android Studio 中Cordova的开发 cordova简介 Cordova的前身是PhoneGap 官网: (http://cordova.io) Cordova应是运行在客户端本地 ...
- mysql 安装运行学习过程中的报错问题
错误记录(windows端): 问题1:在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' ...
- Linux(二)—— Linux配置及指令
目录 Linux配置及指令 一.linux中常用软件的安装 二.主机名和网络 1.修改主机名 2.设置网络 三.关闭防火墙 1.检查防火墙是否开启 2.清除策略 3.永久关闭第一个防火墙 4.关闭第二 ...
- 实用maven笔记一概念&构建
maven,作为我现在每天都会使用的工具,却发现我还有很多地方了解的迷迷糊糊.老大就曾说过我的一个问题在于,做事情不够精细.大概就是太浮于表面吧.最近突然非常想把maven撸一遍.豆瓣搜了下高分书籍, ...
- 线性方程组迭代算法——Gauss-Seidel迭代算法的python实现
原理: 请看本人博客:线性方程组的迭代求解算法——原理 代码: import numpy as np max=100#迭代次数上限 Delta=0.01 m=2#阶数:矩阵为2阶 n=3#维数:3X3 ...
- 小部分安卓手机 reload 等方法不执行
自己解析 url 来赋值刷新页面 方法如下:// location.href function updateUrl(url, key) { var key = (key || 't') + ...
- LeetCode Array Easy 53. Maximum Subarray 个人解法 和分治思想的学习
Description Given an integer array nums, find the contiguous subarray (containing at least one numbe ...