上图是Alert的效果,可以动态的添加和删除里面的alert标签。通过阅读源码可以看出,这个指令把alert封装出来了一个uib-alert指令。通过$attr服务,把uib-alert指令中的属性设置传递到指令中。大家写指令的时候可以借鉴一下。
下面是源码:
angular.module("ui.bootstrap", ["ui.bootstrap.tpls","ui.bootstrap.alert"]);
angular.module("ui.bootstrap.tpls", ["uib/template/alert/alert.html"]);
angular.module('ui.bootstrap.alert', [])
//$attrs当前属性的,并且这里的controller不是父级作用域的的控制器,是指令中的控制器。里面对应的scope也是指令的scope
.controller('UibAlertController', ['$scope', '$attrs', '$interpolate', '$timeout', function($scope, $attrs, $interpolate, $timeout) {
$scope.closeable = !!$attrs.close;
var dismissOnTimeout = angular.isDefined($attrs.dismissOnTimeout) ? //是否设置了自动关闭属性
$interpolate($attrs.dismissOnTimeout)($scope.$parent) : null;
if (dismissOnTimeout) {//如果设置了自动关闭属性,就会触发close()
$timeout(function() {
$scope.close();
}, parseInt(dismissOnTimeout, 10));
}
}])
//uib-alert指令
.directive('uibAlert', function() {
return {
controller: 'UibAlertController',//需要将指令中的方法暴露出去,需要用controller
controllerAs: 'alert',
templateUrl: function(element, attrs) {//templateUrl为函数,需要通过调用attr.templateUrl来获取,如果属性中没有设置,则使用默认的
return attrs.templateUrl || 'uib/template/alert/alert.html';
},
transclude: true,//是否可以替代。
replace: true,
scope: {
type: '@',//把当前属性的值作为字符串传递,使当前指令中template中的子集scope中的中的值,等于父级scope中的值。
close: '&' //传递一个来自父层的函数,稍后调用
}
};
});
//默认的template模板
angular.module("uib/template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("uib/template/alert/alert.html",
"<div class=\"alert\" ng-class=\"['alert-' + (type || 'warning'), closeable ? 'alert-dismissible' : null]\" role=\"alert\">\n" +
" <button ng-show=\"closeable\" type=\"button\" class=\"close\" ng-click=\"close({$event: $event})\">\n" +
" <span aria-hidden=\"true\">×</span>\n" +
" <span class=\"sr-only\">Close</span>\n" +
" </button>\n" +
" <div ng-transclude></div>\n" +
"</div>\n" +
"");
}]);