angular自定义指令详解

指令(directive)是angular里面最核心也是最难懂的东西,在慕课网看了下大漠穷秋老湿的视频,自己百度半天做了一些小test,总算把一切都搞明白了。

先列出学习来源:

指令中controller和link的区别:http://www.cnblogs.com/CreateMyself/p/5568202.html

 

angular视频教程:http://www.imooc.com/learn/156

 

指令中的隔离 Scope :https://blog.coding.net/blog/angularjs-directive-isolate-scope

 

angular学习笔记:https://www.zouyesheng.com/angular.html#toc68

 

 

一、指令的创建:

首先你得先创建一个module:

var module1 = angular.module('module1',[]);
angular.bootstrap(document.body,['module1']);

然后你还得有一个对应的controller:

var module1 = angular.module('module1',[]);module1.controller('ctl1', function($scope) {$scope.content = 'i\'m, module 1';$scope.name = 'module1';$scope.save = function() {console.log('is function save');};
});
angular.bootstrap(document.body,['module1']);
 

 

 

然后你就可以安心的创建指令了:

// 衔接上面的代码
m1.directive('testDirective', function() {// 将对象return出去return{restrict: 'E',// 指令类型 E:element A:attribute M:comment C: classtemplate: '<div>我是指令生成的内容</div>';replace: true, //使用模板替换原始标记 指令内原本的数据将被清空 } });
angular.bootstrap(document.body,['module1']);
 

对应的html可以这样写:

<body><div  ng-controller="ctl1">{{content}}<test-directive>这是原本的内容</test-directive></div>
</body>

以上代码需要注意一下几点:

1.我们定义的指令名称是testDirective,但是在html中要写成test-directive。

2.我们把指令里面的代码都放在了function中的return里面,其实return出去的内容就是整个指令对象。

3.angular.bootstrap(document.body,['module1']);相当于我们在html中使用ng-app指令。推荐使用bootstarp而不是ng-app;

 

 

二、指令的属性

指令的属性如下:

  • name
  • priority
  • terminal
  • scope
  • controller
  • require
  • restrict
  • template
  • templateUrl
  • replace
  • transclude
  • compile
  • link

其中的name、priority、terminal不做详细的介绍。

name就是指令名,对应上面代码中的testDirective,priority多个指令设置在同一个元素上的执行优先级,执行顺序从低至高:1>2>3.priority的值为正整数,比如priority: 1,

terminal, true/false 如果为true,同一个元素上的其他指令的优先级高于本指令,其他指令将停止执行

priority和terminal传送门

1.restrict属性

angular内置的一些指令,比如ng-app,ng-click之类的,都是以html元素的属性(atrrbile)的形式来实现的,我在使用ionic框架的时候,里面有很多自定义的标签、比如:<ion-content></ion-content>。这也是一个指令,他是通过html元素(element)来实现的。除了这两个之外,指令还支持class(html标签的class属性)、commment(html中的注释)来实现。

在JS代码中,restrict可以有以下赋值:

 restrict: 'AE',// 指令类型  E:element A:attribute M:comment C: class

可以是多个restrict: 'AEMC',也可以是一个restrict: 'E'。在html中对应的写法为:

其中注释: <!-- 两边一定要留空格,不然什么都不会发生 -->

 

 

 

 

2.template和templateUrl

同一个指令中只能templatetemplateUrl只能选其一。

template为模板内容。即你要在指令所在的容器中插入的html代码。

template属性接收一个字符串,类似这样:

  template: '<div>我是指令生成的内容</div>';

 

你也可以将整个template写得很复杂,但是,复杂的代码非常不易维护。并且你还得换行,得用字符串拼接每一行。

当你的tamplate超出10行就会显得辣眼睛,过长的template建议使用templateUrl代替。

 

 

templateUrl为从指定地址获取模板内容。即你要在指令所在的容器中插入的一个.html文件。

有了templateUrl我们就可以将想实现的内容写成一个单独的html模版,在需要的地方插入,使用起来会很舒服。

这里的templateUrl类似于JSP中的include,angular也有一个ng-include指令。

具体的详细请点连接:http://www.ziqiangxuetang.com/angularjs/angularjs-include.html

 

 

3.replace和transclude

replace:是否用模板替换当前元素。true : 将指令标签替换成temple中定义的内容,页面上不会再有<my-directive>标签;false :则append(追加)在当前元素上,即模板的内容包在<my-directive>标签内部。默认false。

transculde:是否使用ng-transculde来包含html中指令包含的原有的内容,接收两个参数true/false

先上例子:replace

var app = angular.module("app", []).directive("hello", function () {var option = {restrict: "AECM",template: "<h3>Hello, Directive</h3>",replace: true  //这里replace为true,所以原来的内容会被template代替};return option;})
<html><head></head><body><hello>我是原来的内容</hello> ===> 变成<h3>Hello, Directive</h3>
      如果replace为false ===><hello><h3>Hello, Directive</h3></hello>
</body> 
</html>

transclude:

var app = angular.module("app", []).directive("hello", function () {var option = {restrict: "AECM",template: "<h3>Hello, Directive</h3><span ng-transclude></span>",transculde: true  //这里transculde为true,所以原来的内容会被放在有ng-transclude属性的标签内
        };return option;})
<html><head></head><body><hello>我是原来的内容</hello> ===> 变成<hello><h3>Hello, Directive</h3><span ng-transclude>我是原来的内容</span></hello>
</body> 
</html>

 

4.指令中的scope

directive 默认能共享父 scope 中定义的属性,例如在模版中直接使用父 scope 中的对象和属性。通常使用这种直接共享的方式可以实现一些简单的 directive 功能。

但是,当你要创建一个可以重复使用的directive的时候,就不能依赖于父scope了,因为在不同的地方使用directive对应的父scope不一样。

所以你需要一个隔离的scope,我们可以向下面这样来定义我们的scope。

module1.directive("testDirective", function () {return {scope: {value: '提莫队长正在待命!'},template: 'Say:{{value}}'}
});             

这样就很方便的将我们directive的上下文scope给定义出来了,但是,如果我想将父scope中的属性传递给directive的scope怎么办呢?

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

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

以上三种方式都要在directive的attr属性中进行赋值。上面的话理解起来比较困难,我根据自己的理解做了一下修改:

@:只能绑定字符串,所以一些简单的继承父scope的属性使用@
=: 需要实现双向数据绑定的时候使用=
&: 提供一种方式执行一个表达式在父scope的上下文中,即使用于将父scope中的函数绑定在指令的scope中

以上的理解也许有些偏颇,欢迎指正。

(1)先说@

app.controller("ctl1", function ($scope) {$scope.name = "hello world";}).directive("testDirective", function () {return {scope: {name: "@"},template: 'Say:{{name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="name" class="ng-pristine ng-valid">'}
})
<div ng-controller="ctl1"><div><div>父scope:<div>Say:{{name}}<br>改变父scope的name:<input type="text" value="" ng-model="name"/></div></div><div>隔离scope:这个显示为hello world<div test-directive name="{{name}}"></div></div><div>隔离scope(不使用{{name}}这个就直接显示为name了):<div test-directive name="name"></div> </div></div>

我们在test-directive指令所在的div上面,增加了一个name属性,要使用双花括号来给属性赋值。也可以写成nameCopy:'@nameForCtl',这样写,在给directive中的scope的属性赋值的时候,获取查询@后面的name这个标识对应的属性的值(这里nameForCtl在js中是驼峰写法,同样的在html中对应的属性名应该写成name-for-ctl)。不是很推荐这种写法,感觉有点多余。

(2)=

上一个例子中,我们使用name="{{name}}"的形式来传递父scope 的属性对应的值,so,我们只是把对应的值传递给了directive的scope,当我想实现在directive中改变父scope传递过来的值时,父scope中的值也对应的改变,显然用@这种方法走不通。

这时=就派上用场了。

 app.controller("ctl1", function ($scope) {$scope.user = {name: 'hello',id: 1};}).directive("testDirective", function () {return {scope: {user: "="},template: 'Say:{{user.name}} <br>改变隔离scope的name:<input type="buttom" value="" ng-model="user.name"/>'}})
<div ng-controller="ctl1"><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>

这一个例子和上一个例子不同的地方就是属性赋值的时候,一个应该使用{{}},一个不该使用。=为了实现双向数据绑定,angular会使用‘=’对应的属性的值与父scope中的属性进行匹配,然后传递给diractive中的scope。至于实现的细节和原理,这里我就不说了(其实是不大清楚)。

(3)&

& 方式提供一种途经使directive 能在父 scope 的上下文中执行一个表达式。此表达式可以是一个 function。其实说白了,就是可以使用在父scope中定义的函数。

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

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

在上面的例子中,我们的属性action赋值为一个方法:action="click()",这样一写,一眼就看出来是个什么东西了,好像也没什么好解释的。

 

5.controller、require以及link

 这三个涉及到指令的执行过程,本人暂时还没有比较完全的理解,所以这里只能让大家去看别人写的博客了(原谅我太笨);

连接在顶部。嗯。    ↑点击返回顶部

转载于:https://www.cnblogs.com/ermu-learn/p/5913760.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

delphi7aes加密解密与java互转_跨语言(java vs python vs nodejs)的RSA加解密问题探讨

多次被问到这样的问题&#xff1a;java服务端的rsa加密操作已经完成&#xff0c;返回一个16进制的字符串给python平台&#xff0c;但是在python进行私钥解密的时候发现行不通。。。。前端python加密&#xff0c;后端用java解密&#xff0c;解不出来还有诸如nodejs从理论上来说&…

利用dft的定义计算dft的matlab程序_CP2K教程系列之静态计算(Pymatflow篇)

本系列CP2K教程是《CP2K菜根谭》的升级版&#xff0c;在旧版基础上添加了如何结合Pymatflow工具简化计算流程的内容。话不多说&#xff0c;本文将为您带来CP2K系列教程中的静态计算部分。静态计算设置静态计算是大多数人接触第一性原理计算后第一次运行的计算类型。很多其它类型…

微软是如何戏耍程序员们的

2019独角兽企业重金招聘Python工程师标准>>> 别用微软的东西。商业目的性太强&#xff0c;千万别被微软牵着鼻子走&#xff0c;血淋淋的教训。微软推出的垃圾多了去了。它什么都想做&#xff0c;很多都没做好&#xff1a; MFC&#xff1a;Win31时代出生&#xff0c;…

3d立体相册特效html网页代码_新闻类网页正文通用抽取器

项目起源开发这个项目&#xff0c;源自于我在知网发现了一篇关于自动化抽取新闻类网站正文的算法论文——《基于文本及符号密度的网页正文提取方法》这篇论文中描述的算法看起来简洁清晰&#xff0c;并且符合逻辑。但由于论文中只讲了算法原理&#xff0c;并没有具体的语言实现…

字节数组转换为图片_每日一课 | Python 3 TypeError:无法将“字节”对象隐式转换为str...

将Python 2套接字示例转换为Python 3whois.py import sysimport sockets socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(("whois.arin.net", 43))s.send((sys.argv[1] "\r\n").encode())response ""while True: data s.re…

加速度计和陀螺仪数据融合

本帖翻译自 IMU&#xff08;加速度计和陀螺仪设备&#xff09;在嵌入式应用中使用的指南。这篇文章主要介绍加速度计和陀螺仪的数学模型和基本算法&#xff0c;以及如何融合这两者&#xff0c;侧重算法、思想的讨论介绍本指南旨在向兴趣者介绍惯性MEMS&#xff08;微机电系统&a…

循环嵌套练习题

//BOSS://让用户输入一个奇数&#xff0c;打印菱形&#xff0c;最长的行内容个数为用户输入的个数&#xff0c;并且由英文字母拼接而成//比如用户输入了7// A// ABA// ABCBA// ABCDCBA// ABCBA// ABA// A//1、接收并判断用户输入的是不是数字 try{#region 解法一…

python leetcode_leetcode 介绍和 python 数据结构与算法学习资料

for &#xff08;刚入门的编程&#xff09;的高中 or 大学生leetcode 介绍leetcode 可以说是 cs 最核心的一门“课程”了&#xff0c;虽然不是大学开设的&#xff0c;但基本上每一个现代的高水平的程序员都修过这门“课程”&#xff08;或者类似的课程&#xff0c;比如数据结构…

IOS 为UILabel添加长按复制功能

IOS 为UILabel添加长按复制功能 在iOS中下面三个控件&#xff0c;自身就有复制-粘贴的功能&#xff1a; 1、UITextView 2、UITextField 3、UIWebView UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能。 1、UIPasteboard&#xff1a;我们可以向其…

navicat 的查询功能

navicat的查询的位置在&#xff1a; 在编辑器界面写代码&#xff0c;代码完成后点左上角的运行。 代码&#xff1a; create&#xff08;创建&#xff09; table&#xff08;一个表&#xff09; <xxx>尖括号内的内容必填——我要创建并查询一个名叫做xxx的表 &#xff08…

c++ sleep函数_Linux 多线程应用中如何编写安全的信号处理函数

关于代码的可重入性&#xff0c;设计开发人员一般只考虑到线程安全&#xff0c;异步信号处理函数的安全却往往被忽略。本文首先介绍如何编写安全的异步信号处理函数&#xff1b;然后举例说明在多线程应用中如何构建模型让异步信号在指定的线程中以同步的方式处理。Linux 多线程…

CoreAnimation (CALayer 动画)

CoreAnimation基本介绍&#xff1a; CoreAnimation动画位于iOS框架的Media层CoreAnimation动画实现需要添加QuartzCore.FrameworkCoreAnimation基本上是LayerAnimationCoreAnimation分类&#xff1a; CoreAnimation作用&#xff1a; CoreAnimation CALayer基本介绍 CALayer的常…

汇编为什么分段执行总是执行不了_iOS汇编教程(六)CPU 指令重排与内存屏障...

系列文章iOS 汇编入门教程(一)ARM64 汇编基础iOS 汇编入门教程(二)在 Xcode 工程中嵌入汇编代码iOS 汇编入门教程(三)汇编中的 Section 与数据存取iOS 汇编教程(四)基于 LLDB 动态调试快速分析系统函数的实现iOS 汇编教程(五)Objc Block 的内存布局和汇编表示前言具有 ARM 体系…

GD32 使用stm32 固件库

1、 系统 1) 晶振起振区别 描述&#xff1a;启动时间&#xff0c;GD32 与STM32 启动时间都是2ms&#xff0c;实际上GD 的执行效率快&#xff0c;所以ST 的HSE_STARTUP_TIMEOUT ((uint16_t)0x0500)是2ms&#xff0c;但是这个宏定义值在GD 上时间就更加短了&#xff0c;所以要加大…

js反混淆还原工具_SATURN反混淆框架

本文为看雪论坛精华文章看雪论坛作者ID&#xff1a;梦野间摘要&#xff1a;近几年&#xff0c;软件的混淆强度一直在不断提升。基于编译器的混淆已经成为业界事实上的标准&#xff0c;最近的一些论文也表明软件的保护方式使用的是编译器级别的混淆。在这篇文章中&#xff0c;我…

python 多线程并发_寻找python大神!!!python如何多线程并发?

不是大神。尝试回答一下。 首先解释下什么叫做线程&#xff0c;什么叫做进程&#xff0c;在解释这两个概念前&#xff0c;我们还需要明白什么叫做GIL全局解释器锁。GIL 全局解释器锁&#xff1a; GIL(全局解释器锁&#xff0c;GIL 只有cpython有)&#xff1a;在同一个时刻&…

Nginx/Apache发大招

导读网站程序的上传目录通常是不需要PHP执行解释权限&#xff0c;通过限制目录的PHP执行权限可以提网站的安全性&#xff0c;减少被攻击的机率。下面和大家一起分享下如何在Apache和Nginx禁止上传目录里PHP的执行权限。 Apache下禁止指定目录运行PHP脚本在虚拟主机配置文件中增…

dmp文件查看表空间_innoDb文件

一&#xff0e;文件总体概述InnoDb文件主要有以下文件1. 参数文件&#xff1a;启动需要的各种参数作2. 日志文件&#xff1a;记录mysql实例某种条件做出的响应而写入的文件&#xff0c;如错误日志、二进制日志、慢查询日志、查询日志等3. Socket文件&#xff1a;连接需要的文件…

论文笔记之:Deep Attention Recurrent Q-Network

Deep Attention Recurrent Q-Network 5vision groups 摘要&#xff1a;本文将 DQN 引入了 Attention 机制&#xff0c;使得学习更具有方向性和指导性。&#xff08;前段时间做一个工作打算就这么干&#xff0c;谁想到&#xff0c;这么快就被这几个孩子给实现了&#xff0c;自愧…

linux c程序中内核态与用户态内存存储问题

Unix/Linux的体系架构 如上图所示&#xff0c;从宏观上来看&#xff0c;Linux操作系统的体系架构分为用户态和内核态&#xff08;或者用户空间和内核&#xff09;。内核从本质上看是一种软件——控制计算机的硬件资源&#xff0c;并提供上层应用程序运行的环境。用户态即上层应…