原文: http://seanhess.github.io/2013/10/14/angularjs-directive-design.html

AngularJS directives很酷

AngularJS一个非常好的特色就是可以创建directives, 或者说是可重复利用的web components. 用了directive你可以创建新的HTML标签和属性.

Directive设计原则

如果你想展示一个user列表, 你可以创建一个directive,这个directive读取$scope.users,并且打印出来:

<user-list/>

和ng-repeat比较, ng-repeat只处理重复. user-list和ng-repeat哪一个可以在多个地方使用呢? 如果你需要在两处不同的地方以不同的形式展示user列表呢?

一个好的directive只做一件事情

ng-repeat比user-list好, 因为它只做一件事情: 它只重复部件, 所以你可以在很多环境下重用他.不要让一个directive去处理所有的事情.

一个好的directive不是为某一个应用特定的

通常来说如果你的directive可以在一个完全不同的应用中使用,那么你这个指令应该设计得不错.

如果展示bindings

第一个要学的是directive如何处理binding: 使用一对花括号. 例如, 写一个directive展示一张照片和一段说明.

directive设计的第一步就是选择一个好的属性的名字. 我用photo-src表示image的src, caption作为文本. 小心不要使用其他directive使用过的名字, 比如ng-src 除非你了解他们是怎么工作的.

第二步, 决定支持attributes、classname或element. 在这个例子中我们使用phone作为一个element.

<photo photo-src="{{photo.url}}" caption="Taken on: {{photo.date}}"/>

注意到了没, 我并没有把整个photo对象给到这个directive. 这是一个好的设计, 这样这个directive可以和不同的数据结构数据对象一起工作.

使用 attrs.$observe读取binding. 当binding改变后它会调用你的callback.

app.directive('photo', function() {
return {
// 指定作为element使用
restrict: 'E', // 用下面的html替代<photo>
template: '<figure><img/><figcaption/></figure>',
replace: true, // 观察、操作DOM
link: function($scope, element, attrs) {
attrs.$observe('caption', function(value) {
element.find('figcaption').text(value)
}) // 属性名camel case
attrs.$observe('photoSrc', function(value) {
element.find('img').attr('src', value)
})
}
}
}
})

如果你的component有自己的template, 你可以在一个isolate scope中处理上面所有的attrs.$observe.

app.directive('photo', function() {
return {
restrict: 'E',
templateUrl: 'photo.html',
replace: true,
// pass these two names from attrs into the template scope
scope: {
caption: '@',
photoSrc: '@'
}
}
})

  

<!-- photo.html -->
<figure>
<img ng-src="{{photoSrc}}"/>
<figcaption>{{caption}}</figcaption>
</figure>

如何读写数据

有些directive需要写数据, 比如ng-model.

现在写一个button toggle指令. 这个指令根据scope上面的一些布尔值设置toggle状态, 当被点击这个值发生改变.

这里不使用大括号,而是使用表达式.

<!-- 这里不使用大括号no double curly braces here -->
<button toggle="preferences.showDetails">Show Details</button>

首先我们在scope:里面使用=, 这个设置是为了使得可以在我们的directive中使用scope.toggle.

app.directive('toggle', function() {
return {
scope: {
toggle: '=',
},
link: function($scope, element, attrs) {

下一步我们使用scope.$watch, 当expression改变的时候调用callback. 当toggle改变的时候我们会添加或者删除active类.

$scope.$watch("toggle", function(value) {
element.toggleClass('active', value)
})

最后, 监听jQuery click事件,更新scope. 我们需要使用$scope.$apply 相应改变. 

element.click(function() {
$scope.$apply(function() {
$scope.toggle = !$scope.toggle
})
})
}
}
})

Demo

如何暴露events

有时你想让一个controller响应一个directive里面的事件, 比如ng-click. 创建一个scroll directive, 当用户scroll一个element的使用会调用一个function.

<textarea scroll="onScroll(offset)">...</textarea>

类似于toggle button, 我们映射scroll属性中的function到我们指令的scope.

app.directive('scroll', function() {
return {
scope: {
scroll: "&"
},
link: function($scope, element, attrs) {

我们依然使用scope.$apply

element.scroll(function() {
$scope.apply(function() {
var offset = element.scrollTop()
$scope.scroll({offset:offset})
})
})
}
}
})

Demo

如何包含HTML内容

Directive默认可以有html内容.

写一个modal组件: 一个有关闭按钮的弹出窗口

<modal>
<p>Some contents</p>
<p>Put whatever you want in here</p>
</modal>

modal不止一个元素. 我们写一个template html, 我们在一个div中使用了一个特别的ng-transclude指令 他用来获取得到modal中的html内容.

<div class="modal">
<header>
<button>Close</button>
<h2>Modal</h2>
</header>
<div class="body" ng-transclude></div>
</div>

注意要设置 transclude: true:

app.directive('modal', function() {
return {
restrict: 'E',
templateUrl: 'modal.html',
replace: true,
transclude: true,
}
})

[译]angularjs directive design made easy的更多相关文章

  1. 学习AngularJs:Directive指令用法(完整版)

    这篇文章主要学习AngularJs:Directive指令用法,内容很全面,感兴趣的小伙伴们可以参考一下   本教程使用AngularJs版本:1.5.3 AngularJs GitHub: http ...

  2. 学习AngularJs:Directive指令用法

    跟我学AngularJs:Directive指令用法解读(上) http://blog.csdn.net/evankaka/article/details/51232895 跟我学AngularJs: ...

  3. angularjs directive 实例 详解

    前面提到了angularjs的factory,service,provider,这个可以理解成php的model,这种model是不带html的,今天所说的directive,也可以理解成php的mo ...

  4. Angularjs directive全面解读(1.4.5)

    说到Angularjs directive即指令,可以这么说Angularjs的灵魂就是指令,学会Angularjs指令那么你的Angularjs的武功就修炼了一半了,当然这只是鄙人的一点点独到见解, ...

  5. [译]AngularJS 1.3.0 开发者指南(一) -- 介绍

    [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 Angular是什么 ? AngularJS是一款针对动态web应用的结构框架. 它可以让像使用模板语言使用HTML, 并且可以扩展 ...

  6. angularjs directive (自定义标签解析)

    angularjs directive (自定义标签解析) 定义tpl <!-- 注意要有根标签 --> <div class="list list-inset" ...

  7. 170. Two Sum III - Data structure design【easy】

    170. Two Sum III - Data structure design[easy] Design and implement a TwoSum class. It should suppor ...

  8. [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 (转)

    http://www.cnblogs.com/lzj0616/p/6440563.html [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 Angular是什么 ? Angular ...

  9. 50.AngularJs directive详解及示例代码

    转自:https://www.cnblogs.com/best/tag/Angular/ 本教程使用AngularJs版本:1.5.3 AngularJs GitHub: https://github ...

随机推荐

  1. Python基础4:数据类型:数字 字符串 日期

    [ Python 数据类型 ] 我们知道,几乎任何编程语言都具有数据类型:常见的数据类型有:字符串.整型.浮点型以及布尔类型等. Python也不例外,也有自己的数据类型,主要有以下几种: 1.数字: ...

  2. dedecms /include/helpers/archive.helper.php SQL Injection Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Dedecms会员中心注入漏洞 Relevant Link: http: ...

  3. Windows装机必备软件列表

    经常装系统,列个List,以后装完之后安装软件直接参照使用!windows版: 输入法: 搜狗输入法(由于长期使用导致此输入法十分熟悉我的输入习惯,以无法自拔).支持Linux.Windows(太穷还 ...

  4. Swift Swift中的反射

    Swift的反射机制是基于一个叫 Mirror 的 struct 来实现的,其内部有如下属性和方法: let children: Children //对象的子节点. displayStyle: Mi ...

  5. python 生成器和递归

    生成器 1.定义 问题:python会把对象放到内存中,我们每次定义变量.列表等都会在内存中占用对应的地址块,所以当内存容量一定时,列表的容量会受到内存的限制,而且假如我们创建了一个包含200万个元素 ...

  6. PHP之:PHP编程效率的20个要点

    [导读] 用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则 不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数” 用单引号 ...

  7. Handler,Thread,Looper之间关系小结

    http://blog.csdn.net/sunxingzhesunjinbiao/article/details/6794840 (1) Looper类别用来为一个线程开启一个消息循环.默认情况下A ...

  8. Jboss7.1 加入realm auth认证 bootsfaces 美化的登录页面

    jboss-as-7.1.1.Final\standalone\configuration: 1, standalone.xml中 <security-domains>标签里面添加: &l ...

  9. BZOJ1798: [Ahoi2009]Seq 维护序列seq

    传送门 写这道题是为了get一个同时传送乘法下标和加法下标的小技巧,线段树模板题.不多说. 标记名字打错无限智力-- //BZOJ 1798 //by Cydiater //2016.9.13 #in ...

  10. javascript之简单的选择排序法

    基本思想: 比对数组中元素,相等者输出元素在数组的下标,否则就输出没找到! 代码如下: function Orderseach(array,findVal){ var temp = false; // ...