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 概念的更多相关文章

  1. 转载 《AngularJS》5个实例详解Directive(指令)机制

    <AngularJS>5个实例详解Directive(指令)机制 大漠穷秋 本文整理并扩展了<AngularJS>这本书第六章里面的内容,此书近期即将由电子工业出版社出版,敬请 ...

  2. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  3. 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 ...

  4. 详解Objective-C中委托和协议

    Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...

  5. 详解javascript中的this对象

    详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...

  6. 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)

    用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是 ...

  7. (转载)详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  8. 详解JavaScript中的原型

    前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...

  9. 详解Spring中Bean的作用域与生命周期

    摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...

随机推荐

  1. 【dart学习】-- Dart之JSON

    概述 现在很难想象移动应用程序不需要与后台交互或者存储结构化数据.现在开发,数据传输方式基本都是用JSON,在Flutter中是没有GSON/Jackson/Moshi这些库,因为这些库需要运行时反射 ...

  2. Python之-在字典、列表、集合中刷选数据

    一.元组.字典.列表的遍历 1.元组遍历 元组的遍历借助 range() 函数,基本思想是通过元组的长度使用for循环进行遍历 #troup s = ["aaa","bb ...

  3. 20175213 2018-2019-2 《Java程序设计》第10周学习总结

    Java内存模型 主内存与工作内存 Java内存模型主要目标:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节.此处的变量(Variable)与Java编程中 ...

  4. (54) C# 调用 kernel32.dll

    https://www.cnblogs.com/cwy173/archive/2010/10/02/1841321.html Kernel32 API AddAtom 向本地原子表添加一个字符串 Al ...

  5. 【痛定思痛】TCP 三次握手学习

    前言:今天滴滴面试失败,痛定思痛,好好复习面试中最惨淡的计算机网络部分 面试中,面试官问我TCP与UDP最大的区别是什么,答:TCP可靠,UDP不可靠,一个面向有连接,一个面向无连接,一个快一个慢:追 ...

  6. Django框架(三十)—— 使用Vue搭建前台

    目录 vue的使用 一.创建vue项目 二.pycharm开发vue项目 1.安装vue.js插件 2.运行vue项目 三.vue项目的目录结构 四.vue的使用 1.创建新的组件 2.显示数据 3. ...

  7. 洛谷 P2023 维护序列——线段树

    先上一波题目 https://www.luogu.org/problem/P2023 复习了一波线段树 题目涉及的操作有区间加 区间乘以及区间求和 tips:线段树在传标记的时候 优先传乘法标记再传加 ...

  8. leetcode.双指针.633平方数之和-Java

    1. 具体题目 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 + b^2 = c. 示例1: 输入: 5 输出: True 解释: 1 * 1 + 2 * 2 = 5 注 ...

  9. Scrapy框架: settings.py设置

    # -*- coding: utf-8 -*- # Scrapy settings for maitian project # # For simplicity, this file contains ...

  10. java selenium爬取验证图片是否加载完成

    爬虫任务里发现有部分图片没有加载完成就进行文件流上传,导致有一些图片是空白,需要判断一下: 首选获取image标签元素: WebElement image = driver.findElement(B ...