发布于 2015-09-06 14:45:33 | 286 次阅读 | 评论: 0 | 来源: 网络整理
regularjs中指令的定位是: 针对某一个节点的特定功能增强, 因为regularjs把大部分抽象的职责都迁移到了组件这个概念中。
每一个组件可以通过Component.directive
来扩展指令. 定义接近于angular, 但是极度简化:
link(element, value, attrs): 链接函数
r-model='blog.title'
r-model={blog.title}
value是一个Expression对象priority: 指令权重, 默认为1, 一个节点上得指令初始化顺序根据指令权重按序执行.
除此之外,再无其它。 无需去关心prelink, postlink, compile, transclude, controll, scope 等等angularjs中令人眼花缭乱的概念.
如果这个指令需要回收(比如link中创建了其它dom元素等), link函数需要返回一个函数用于指令销毁工作.
Regular.directive("date-picker", function(){
// blabla....
return function (){
// for destory directive
}
})
上例中我们直接传入了函数, 这是一种简写方式, 此函数会成为指令定义的link函数.
Question: 为什么要返回销毁函数, 而不是通过监听 $destroy
事件来完成 ?
Answer: 因为指令的销毁并不一定伴随着组件销毁, 指令的生命周期更短, 一些语法元素会导致它在组件销毁之前被重复创建和销毁:
不过值得庆幸的是,一切关于数据监听的事务, 都无需回收, regularjs回进行自动记录以及收集.
在这一小节, 我们会实现一个ng-model
来实现一个简单的表单双向绑定
Example
<input type="text" ng-model={user.name} >
即ng-model
使得此表单节点元素获得了双向绑定的能力, 它与user.name实现了双向绑定,
假如要实现这个功能, 很明显需要做两件事情:
代码实现如下:
Regular.directive("ng-model", function(elem, exression){
// make sure the exression is An Expression
var self = this;
this.$watch( exression, function( nval ){
elem.value = nval;
})
function updateModel(){
exression.set(self, elem.value);
self.$update(); // enter digest
}
elem.addEventListener("input", updateModel);
})
这个DEMO缺陷还很多, 比如:
ng-model='user.name'
这样输入是文本而不是表达式的容错处理但是不用担心, regularjs中已经内置了r-model来实现更通用的支持. (所有内置指令都会以r-
开头)
因为组件概念的存在, regularjs中指令的作用被大大弱化(angular中将组件化与指令杂糅在了一起), 但是对于针对具体节点的功能性增强, 我们仍然推荐使用指令来解决,而不是手动的操作dom. 原因如下:
r-model
指令, 如果手动实现,你仍然需要大量的代码声明式的指令理解起来更加直观
事实上, regularjs在文档中隐瞒了这一点: 指令是可以后续主动绑定的, 不一定要通过模板生成。 例如
init: function(){
var directiveModel = Regular.directive("r-model");
var input = this.$refs.input;
directiveModel.link.call(this, input, 'blog.title');
}
$refs请参见文档, 它用于获取模板中标记的节点或组件. 当directive方法不传入factory时, 它成为一个getter方法,用于获取指定的指令
但是在表现力上, 它仍然没有在模板中声明来的直观. 并且模板中得指令是会自动进行回收的.