前言:
前一段时间接触了Angular框架,这是一款非常实用的JS框架,它可以大大减少直接对页面元素的操作,使复杂功能的实现更简单。AngularJS有着诸多特性,最为核心的是:MVW(Model-View-Whatever)、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。想要真正把Angular的优势发挥到极致,还是需要转变传统前端编码思路的,更多的把注意力放在数据模型的设计上,更多的运用一些后台编程思想。废话不多说,直接开始今天的正文。
我项目中使用较多前端UI框架时layui,当初选择layui主要是因为觉得layui使用简单。但是把Angular和layui结合起来使用的话,经常会遇到一些表单元素概率性刷新不出来的情况。究其根本原因无非就是页面元素加载和js代码执行顺序的问题,说白了就是layui的js代码需要根据自己逻辑处理页面元素的时候,但是页面元素还未生成或者加载成功。最常见的场景就是在页面代码使用了ng-repeat,ng-repeat中又有一些需要layui.form.render方法才能刷新出来的元素,这时由于执行render的时机不对就会产生页面元素概率刷新不出来的问题。借此我们引出angular的第一个使用技巧---自定义指令。
Angular自定义指令
js代码片段
app.directive('onFinishRender',['$timeout','$parse',function($timeout,$parse){
return {
restrict: 'A',
link: function(scope,element,attr){
if(scope.$last === true){
$timeout(function(){
scope.$emit('ngRepeatFinished');
var fun = scope.$eval(attr.onFinishRender);
if(fun && typeof(fun) == 'function' ){
fun();
}
});
}
}
}
}])
页面使用指令片段
上面的代码中我们自定义了一个on-finish-render的指令,这个指令能实现这样一个功能:在ng-repeat元素加载完成之后,会产生一个ngReapeatFinished事件,同时on-finish-render属性可以是一个方法名,元素加载完成之后会执行这个方法名对应的方法。我们也可以使用$scope.$on方法来监听ngReapeatFinished事件,以便加入我们的逻辑。实际项目中我们可以使用app的$rootScope来监听此事件,统一执行元素刷新操作。
再聚一个自定义标签的例子
模板代码
js代码
app.directive('modalTitle', function () {
return {
restrict: 'EA',
templateUrl: 'tpls/modal-title.html',
scope:{
title:'@',
close:'&'
}
}
}
);
指令的使用
利用directive的特性,我们还可以做很多事情,在此列出directive的全部属性有兴趣的同学可以挨个属性的用法了解一下。相关的文档很多,在此就不做细说了。
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: String,
priority: Number,
terminal: Boolean,
template: String or Template Function:
function(tElement, tAttrs) (...},
templateUrl: String,
replace: Boolean or String,
scope: Boolean or Object,
transclude: Boolean,
controller: String or
function(scope, element, attrs, transclude, otherInjectables) { ... },
controllerAs: String,
require: String,
link: function(scope, iElement, iAttrs) { ... },
compile: // 返回一个对象或连接函数,如下所示:
function(tElement, tAttrs, transclude) {
return {
pre: function(scope, iElement, iAttrs, controller) { ... },
post: function(scope, iElement, iAttrs, controller) { ... }
}
// 或者
return function postLink(...) { ... }
}
}; });