angularjs 指令详解 - template, restrict, replace
通过指令机制,angularjs 提供了一个强大的扩展系统,我们可以通过自定义指令来扩展自己的指令系统。
怎样定义自己的指令呢?
我们通过 Bootstrap UI来学习吧。这个项目使用 angularjs 将 Bootstrap 3 进行了封装,是我们学习 angularjs 很好的样例。
从 Alert 开始
首先,我们从比较简单的 alert 指令来开始学习。
在 Bootstrap 中,警告框使用类 alert 来表示, 通过 alert-success, alert-info, alert-warning, alert-danger 来表示不同类型的警告。
<div class="alert alert-success">...</div>
<div class="alert alert-info">...</div>
<div class="alert alert-warning">...</div>
<div class="alert alert-danger">...</div>
对于可关闭的警告框来说,还可以用一个可选的.alert-dismissable和关闭按钮,但是,这是通过脚本来实现的,在 bootstrap ui 这里没有使用。
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<strong>Warning!</strong> Best check yo self, you're not looking too good.
</div>
bootstrap UI 中的用法
在 Bootstrap UI 的示例中,我们可以直接通过自定义的 alert 来定义一个提示。其中的 type 用来定义提示的类型,提示的信息内容通过绑定来处理。
<div ng-controller="AlertDemoCtrl">
<alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
<button class='btn btn-default' ng-click="addAlert()">Add Alert</button>
</div>
对应的脚本
function AlertDemoCtrl($scope) {
$scope.alerts = [
{ type: 'danger', msg: 'Oh snap! Change a few things up and try submitting again.' },
{ type: 'success', msg: 'Well done! You successfully read this important alert message.' }
];
$scope.addAlert = function() {
$scope.alerts.push({msg: "Another alert!"});
};
$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
};
}
bootstrap UI 中的定义
下面就是指令的定义了。
angular.module('ui.bootstrap.alert', [])
.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
$scope.closeable = 'close' in $attrs;
}])
.directive('alert', function () {
return {
restrict:'EA',
controller:'AlertController',
templateUrl:'template/alert/alert.html',
transclude:true,
replace:true,
scope: {
type: '@',
close: '&'
}
};
});
最终生成的标记为:
<div ng-controller="AlertDemoCtrl" class="ng-scope">
<!-- ngRepeat: alert in alerts -->
<div class="alert ng-isolate-scope alert-danger" ng-class=""alert-" + (type || "warning")" ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">
<button ng-show="closeable" type="button" class="close" ng-click="close()">×</button>
<div ng-transclude=""><span class="ng-scope ng-binding">Oh snap! Change a few things up and try submitting again.</span></div>
</div> <!-- end ngRepeat: alert in alerts -->
<div class="alert ng-isolate-scope alert-success" ng-class=""alert-" + (type || "warning")" ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">
<button ng-show="closeable" type="button" class="close" ng-click="close()">×</button>
<div ng-transclude=""><span class="ng-scope ng-binding">Well done! You successfully read this important alert message.</span></div>
</div><!-- end ngRepeat: alert in alerts -->
<button class="btn btn-default" ng-click="addAlert()">Add Alert</button>
</div>
看不懂!没有关系,我们慢慢来。
从模版开始
比如说,在下面的代码中,你希望通过 my-customer 将一个内容为空白的 div 变成内容为绑定名字和地址的文本内容
<div ng-controller="Ctrl">
<div my-customer></div>
</div>
比如生成下面的结果:
<div ng-controller="Ctrl">
<div>Name: {{customer.name}} Address: {{customer.address}}</div>
</div>
内嵌模版
对于以上的要求,我们可以定义一个名为 my-customer 的指令。然后,说明这个指令将会生成元素中间的内容,我们称之为模版的内容。
angular.module('docsSimpleDirective', [])
.controller('Ctrl', function($scope) {
$scope.customer = {
name: 'Naomi',
address: '1600 Amphitheatre'
};
})
.directive('myCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
directive 表示我们要定义一个自定义的指令,指令的名称为 myCustomer,后面的函数用来定义指令的特征
template 表示我们的指令使用的模版,你会看到,它的值就是我们准备生成的内容。
不过,你会说,且慢,我希望使用 myCustomer 元素,而不是 Attribute ,那又该怎么办呢?
默认情况下,指令只能作为元素的 attribute 使用,如果希望用在其它的地方,那么你需要学习第二个属性 restrict
指令的使用范围
restrict 的取值可以有三种:
- A 用于元素的 Attribute,这是默认值
- E 用于元素的名称
- C 用于 CSS 中的 class
比如说,我们这样定义指令。
var app = angular.module("app", [])
.directive("hello", function () {
var option = {
restrict: "AEC",
template: "Hello, Directive",
};
return option;
})
由于我们指定了可以用于三种情况下,那么,就可以如下三种形式来使用这个指令
<!-- 元素 -->
<div>
<hello></hello>
</div> <!-- 属性-->
<div>
<div hello></div>
</div> <!-- class -->
<div>
<div class="hello"></div>
</div>
输出的结果分别如下:
<!-- 元素 -->
<div>
<hello>Hello, Directive</hello>
</div>
<!-- 属性-->
<div>
<div hello="">Hello, Directive</div>
</div>
<!-- class -->
<div>
<div class="hello">Hello, Directive</div>
</div>
替换元素
下一个你需要知道的参数为 replace,顾名思义,这是替换的意思,默认为 false,就是将模版的内容追加到元素中,如果设置为 true,那么模版的内容将会替换元素的内容。
原来的输出将会成为下面的样子,实际上,你在页面中将会看不到输出的内容,hello 元素浏览器是不认识的,而其它两种方式,我们又没有生成任何的元素。
<!-- 元素 -->
<div>
<hello></hello>
</div>
<!-- 属性-->
<div>
<div hello=""></div>
</div>
<!-- class -->
<div>
<div class="hello"></div>
</div>
如果我们将模版更新为一个元素,如下所示。
var app = angular.module("app", [])
.directive("hello", function () {
var option = {
restrict: "AECM",
template: "<h3>Hello, Directive</h3>",
replace: true
};
return option;
})
这次,你将会看到在 replace 为 true 情况下的元素了。
<!-- 元素 -->
<div>
<h3>Hello, Directive</h3>
</div>
<!-- 属性-->
<div>
<h3 hello="">Hello, Directive</h3>
</div>
<!-- class -->
<div>
<h3 class="hello">Hello, Directive</h3>
</div>
transclusion 嵌入
如果我们在上面的元素中这么写会怎样呢?
<!-- 元素 -->
<div>
<hello>12345678</hello>
</div>
你会发现 12345678 消失了,这个元素完全被模版替换了。如果我们需要保留这些内容怎么处理呢?
transclusion 指的是定义模版的元素如何处理问题,比如,在使用指令的时候,指令中包含了内容,那么这些内容我们是否直接被替换为模版,还是将这些内容嵌入到模版中。
在使用它的时候,需要在两个地方说明,一是在指令中说明需要嵌入,二是在模版中说明嵌入到哪里。
var app = angular.module("app", [])
.directive("hello", function () {
var option = {
restrict: "AECM",
template: "<h3>Hello, Directive, <span ng-transclude></span></h3>",
replace: true,
transclude: true
};
return option;
})
然后,在模版中说明嵌入的位置。
template: "<h3>Hello, Directive, <span ng-transclude></span></h3>",
页面中的使用。
<hello>12345678</hello>
最后,生成的结果如下。
<h3>Hello, Directive, <span ng-transclude=""><span class="ng-scope">12345678</span></span></h3>
看看 alert 使用的模版
模版的实际定义如下。
<div class="alert" ng-class="{'alert-{{type || 'warning'}}': true, 'alert-dismissable': closeable}" role="alert">
<button ng-show="closeable" type="button" class="close" ng-click="close()">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<div ng-transclude></div>
</div>
在生成之后,alert 被替换为了 div 元素,至于关闭按钮是否显示出来,取决于 closeable 属性的值。
replace 定义为真,表示使用模版的定义替换原来的元素,而 transclude 用来把内容填充到目标位置。在内嵌的 div 元素中使用了 ng-transclude 指示了填充的目标位置。
angularjs 指令详解 - template, restrict, replace的更多相关文章
- AngularJS指令详解
一.什么是指令? 在<AngularJs权威教程>中,指令可以简单理解成特定的DOM元素上运行的函数:我认为还可以理解成将将自定义的HTML标签解析成原始的标签,然后为其加入一些扩展的功能 ...
- angularjs 指令详解
一.指令定义 对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素的功能. 首先来看个完整的参数示例再来详细的介绍各个参数的作用及用法: <div my-direct ...
- 迈向angularjs2系列(2):angular2指令详解
一:angular2 helloworld! 为了简单快速的运行一个ng2的app,那么通过script引入预先编译好的angular2版本和页面的基本框架. index.html: <!DOC ...
- [转]JVM指令详解(上)
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码 助记符 ...
- C#中的预处理器指令详解
这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...
- rsync指令详解
rsync指令详解(更详细的看官方文档http://rsync.samba.org/ftp/rsync/rsync.html) [root@Centos epel]# rsync --help rsy ...
- #pragma 预处理指令详解
源地址:http://blog.csdn.net/jx_kingwei/article/details/367312 #pragma 预处理指令详解 在所有的预处理指令中, ...
- LDM与STM指令详解
title: LDM与STM指令详解 date: 2019/2/26 17:58:00 toc: true --- LDM与STM指令详解 指令形式如下,这里的存储方向是针对寄存器的 Load Mul ...
- C#中的预处理指令详解
这篇文章主要介绍了C#中的预处理指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregion ...
随机推荐
- 一次mongodb 统计需求
需求: 临下班运营的同事发来了一个需求,要统计数据库里某个collection的所有document 中某个字段(_id)出现的次数._id 字段的范围是0-4000. 假设collection 是这 ...
- ZoomEye 钟馗之眼 搜索工具 基于API
#!/usr/bin/env python # -*- coding: utf-8 -*- # Author: f0rsaken import getopt import requests impor ...
- Servlet规范简介——web框架是如何注入到Servlet中的
Servlet规范简介--web框架是如何注入到Servlet中的 引言 Web框架一般是通过一个Servlet提供统一的请求入口,将指定的资源映射到这个servlet,在这个servlet中进行框架 ...
- RTX二次开发集成
1,rtx服务器端有很多端口,二次发的程序与这些打开的端口交互.打开端口的方法在rtx服务管理器中,默认http服务未启用.需要手动启用http端口如下: 如果打开rtx服务器没有启用http的801 ...
- Python中的生成器与yield
对于python中的yield有些疑惑,然后在StackOverflow上看到了一篇回答,所以搬运过来了,英文好的直接看原文吧. 可迭代对象 当你创建一个列表的时候,你可以一个接一个地读取其中的项.一 ...
- Can't load IA 32-bit .dll on a AMD 64-bit platform错误的解决
64位的系统,64位的myeclipse,64位的jdk,64位的tomcat,结果报错:Can't load IA 64-bit .dll on a AMD 32-bit platform,简直无语 ...
- 2分钟 sublime设置自动行尾添加分号并换行:
18:03 2016/4/162分钟 sublime设置自动行尾添加分号并换行:注意:宏文件路径要用反斜杠/,2个\\会提示无法打开宏文件.不需要绝对路径很简单利用宏定义:1.录制宏:由于是录制动作宏 ...
- Python几种常用的测试框架
一.测试的常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过 ...
- Golang之chan/goroutine(转)
原文地址:http://tchen.me/posts/2014-01-27-golang-chatroom.html?utm_source=tuicool&utm_medium=referra ...
- lua 字符串 正则表达式 转义 特殊字符
string.gsub 函数有三个参数:目标串,模式串,替换串.基本作用是用来查找匹配模式的串,并将使用替换串其替换掉: s = string.gsub("Lua is good" ...