在 angularJS 中如何重叠指令(指令之一 angular-bootstrap)
How overlapping directive(one of directives angular-bootstrap) in angularJS
我使用 lib angular-bootstrap,并且我有一个指令重叠:
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
return {
restrict: 'EA',
require: 'ngModel',
scope: {
isOpen: '=?',
currentText: '@',
clearText: '@',
closeText: '@',
dateDisabled: '&'
},
link: function(scope, element, attrs, ngModel) {
/* Other code in lib */
scope.$watch('isOpen', function(value) {
if (value) {
console.log("watch lib dir");
scope.$broadcast('datepicker.focus');
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
scope.position.top = scope.position.top + element.prop('offsetHeight') + 50;
$document.bind('click', documentClickBind);
} else {
$document.unbind('click', documentClickBind);
}
});
/* Other code in lib */
}
};
}])
我创建了自定义指令,而不是使用 require 指令(因为在 html 布局中我使用这个指令作为属性,除了另一个属性我不能,因为它不属于第一个属性),但只是简单地写了相同的签名:
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
return {
restrict: 'EA',
priority: 1,
link: function(scope, element, attrs, ngModel) {
scope.$watch('isOpened', function(value) {
if(value){
/*custom code */
}
});
}
};
}])
但是 scope.$watch 看不到 'isOpened'(因此无法更正),我在定义自定义指令中添加了:
scope: {
isOpen: '=?'
}
然后在控制台中捕获抛出异常:
Error: [$compile:multidir] Multiple directives [datepickerPopup, datepickerPopup] asking for new/isolated scope on: <input type="text" name="callDate" class="form-control ng-pristine ng-untouched ng-valid" ng-model="callDate" datepicker-popup="MM/dd/yyyy" datepicker-positioning="" is-open="opened" ng-required="true">
如何不使用 require 来重叠 lib 指令?
是的,因为您无法在 Angular 中重新定义指令。您需要使用装饰器来 extend/replace 它们。
app.config(function ($provide) {
$provide.decorator('datepickerPopupDirective', ['$delegate', '$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig', function($delegate, $compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
return {
restrict: 'EA',
priority: 1,
scope: {
isOpen: '=?'
},
link: function(scope, element, attrs) {
scope.$watch('isOpen', function(value) {
if(value){
/*custom code */
}
});
}
};
}]);
});
如果您不打算扩展原始指令,则可以省略 $delegate
依赖项。
我使用 lib angular-bootstrap,并且我有一个指令重叠:
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
return {
restrict: 'EA',
require: 'ngModel',
scope: {
isOpen: '=?',
currentText: '@',
clearText: '@',
closeText: '@',
dateDisabled: '&'
},
link: function(scope, element, attrs, ngModel) {
/* Other code in lib */
scope.$watch('isOpen', function(value) {
if (value) {
console.log("watch lib dir");
scope.$broadcast('datepicker.focus');
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
scope.position.top = scope.position.top + element.prop('offsetHeight') + 50;
$document.bind('click', documentClickBind);
} else {
$document.unbind('click', documentClickBind);
}
});
/* Other code in lib */
}
};
}])
我创建了自定义指令,而不是使用 require 指令(因为在 html 布局中我使用这个指令作为属性,除了另一个属性我不能,因为它不属于第一个属性),但只是简单地写了相同的签名:
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
return {
restrict: 'EA',
priority: 1,
link: function(scope, element, attrs, ngModel) {
scope.$watch('isOpened', function(value) {
if(value){
/*custom code */
}
});
}
};
}])
但是 scope.$watch 看不到 'isOpened'(因此无法更正),我在定义自定义指令中添加了:
scope: {
isOpen: '=?'
}
然后在控制台中捕获抛出异常:
Error: [$compile:multidir] Multiple directives [datepickerPopup, datepickerPopup] asking for new/isolated scope on: <input type="text" name="callDate" class="form-control ng-pristine ng-untouched ng-valid" ng-model="callDate" datepicker-popup="MM/dd/yyyy" datepicker-positioning="" is-open="opened" ng-required="true">
如何不使用 require 来重叠 lib 指令?
是的,因为您无法在 Angular 中重新定义指令。您需要使用装饰器来 extend/replace 它们。
app.config(function ($provide) {
$provide.decorator('datepickerPopupDirective', ['$delegate', '$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig', function($delegate, $compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
return {
restrict: 'EA',
priority: 1,
scope: {
isOpen: '=?'
},
link: function(scope, element, attrs) {
scope.$watch('isOpen', function(value) {
if(value){
/*custom code */
}
});
}
};
}]);
});
如果您不打算扩展原始指令,则可以省略 $delegate
依赖项。