源码非常简单,大家可以借鉴一下,其指令继承自己的方式来传递contant中的配置。
angular.module("ui.bootstrap", ["ui.bootstrap.tpls","ui.bootstrap.buttons"]);
angular.module("ui.bootstrap.tpls", []);
angular.module('ui.bootstrap.buttons', [])
//constant 对于指令来说,经常用来保存配置信息
.constant('uibButtonConfig', {
activeClass: 'active', //类名
toggleEvent: 'click' //触发事件
})
//声明一个单独的控制器,用来给指令传递信息。把constant保存的信息,传递到指令中的controller中。
.controller('UibButtonsController', ['uibButtonConfig', function(buttonConfig) {
this.activeClass = buttonConfig.activeClass || 'active';
this.toggleEvent = buttonConfig.toggleEvent || 'click';
}])
//
.directive('uibBtnRadio', ['$parse', function($parse) {
return {
require: ['uibBtnRadio', 'ngModel'],//继承自己的指令,把controller继承进来
controller: 'UibButtonsController',//controller
controllerAs: 'buttons',//别名
link: function(scope, element, attrs, ctrls) {
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1]; //分别保存继承来的控制器
var uncheckableExpr = $parse(attrs.uibUncheckable);//解析字符串 uib-uncheckable
element.find('input').css({display: 'none'}); //设置样式
//model -> UI
ngModelCtrl.$render = function() {
element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.uibBtnRadio)));
//通过判断ngModelCtrl.$modelValue与attrs.uibBtnRadio是否相等来触发
};
//ui->model
element.on(buttonsCtrl.toggleEvent, function() {//绑定事件
if (attrs.disabled) {
return;
}
var isActive = element.hasClass(buttonsCtrl.activeClass);//是否有active类名
if (!isActive || angular.isDefined(attrs.uncheckable)) {//如果没有Active类名,则添加一个uib-Btn-Radio属性的值
scope.$apply(function() {
ngModelCtrl.$setViewValue(isActive ? null : scope.$eval(attrs.uibBtnRadio));
//设置viewValue的值,如果isActive为true,则代表有了acitve类,就设为null,否则为uib-Btn-Radio的值。用来设置指令中ng-modal的值。
ngModelCtrl.$render();
});
}
});
if (attrs.uibUncheckable) {
scope.$watch(uncheckableExpr, function(uncheckable) {
attrs.$set('uncheckable', uncheckable ? '' : undefined);
});
}
}
};
}])