尝试将自定义指令与datepicker结合使用时出现以下错误:
Multiple directives [arValidations, datepickerPopup] asking for new/isolated scope on...
所以我想我需要删除孤立的范围,问题是我不知道如何。这是我的指示:
app.directive('arValidations', [ 'BaseValidator', '$injector', function(BaseValidator, $injector){
return {
restrict: 'A',
scope: { arValidations: '@?' },
require: '?ngModel',
link: function(scope, element, attrs, ngModel){
scope.validations = JSON.parse(scope.arValidations);
scope.Validator = $injector.get(scope.validations.validator);
scope.pristine = true;
scope.BaseValidator = BaseValidator;
scope.$watch(function(){ return ngModel.$modelValue }, function (attr) {
var label = scope.validations["attribute"];
var types = scope.Validator.attributes[label].types;
var validated = scope.BaseValidator.validateValue(types, attr);
scope.Validator.attributes[label].valid = validated === true && scope.pristine === false;
scope.Validator.allValid = scope.BaseValidator.updateAllValidations(scope.Validator.attributes);
scope.pristine = false;
if(scope.Validator.attributes[label].valid){
element.removeClass('valid-input');
element.addClass('valid-input');
} else{
element.removeClass('valid-input');
}
});
}
}
}]);
主要问题是我在该指令的每个实例中注入了不同的服务。有什么建议吗?
编辑:我在评论中多次说过,但使用arValidations
获取attrs
属性而不是隔离范围不提供相同的功能,因为同一指令的多个实例可以在同一范围内创建,覆盖scope.Validator
。
解决方案是将2个指令分成几个元素以保持范围隔离。所以这是我今天的作业:
指令:
app.directive('validatedDatepicker', function(){
return {
templateUrl: 'directives/validated_datepicker.html',
scope: { modelInstance: '=validatedDatepicker', modelAttribute: '@?', placeholder: '@?', maxDate: '=?' },
controller: ['$scope', 'BaseValidator', '$injector', function($scope, BaseValidator, $injector){
$scope.cssClass = { 'valid-input': false };
$scope.Validator = $injector.get($scope.modelInstance.$validator);
$scope.pristine = true;
$scope.BaseValidator = BaseValidator;
$scope.calendarDisplay = false;
$scope.openDate = function(e){
e.preventDefault();
e.stopPropagation();
$scope.calendarDisplay = true;
};
$scope.$watch(function(){ return $scope.modelInstance[$scope.modelAttribute]; }, function (attr) {
var label = $scope.modelAttribute;
var types = $scope.Validator.attributes[label].types;
var validated = $scope.BaseValidator.validateValue(types, attr);
$scope.Validator.attributes[label].valid = validated === true && $scope.pristine === false;
$scope.Validator.allValid = $scope.BaseValidator.updateAllValidations($scope.Validator.attributes);
$scope.pristine = false;
if($scope.Validator.attributes[label].valid){
$scope.cssClass = { 'valid-input': true };
} else{
$scope.cssClass = { 'valid-input': false };
}
});
}]
}
});
模板:
<input placeholder="{{placeholder}}" ng-class="cssClass" type="text" show-button-bar="false" class="form-control required-input" datepicker-popup="dd-MM-yyyy" data-ng-model="modelInstance[modelAttribute]" max-date="modelInstance[maxDate]" is-open="calendarDisplay" close-text="Close"/>
<div class="input-group-addon" data-ng-click="openDate($event)"><i class="fa fa-calendar"></i></div>
编辑2:为了完整性,scope: true
会出现与scope: {}
相同的错误。
答案 0 :(得分:0)
如果arValidations
应该与相同元素上的其他指令一起使用(我认为是这种情况),那么不应该创建一个隔离的范围,而是共享与其他指令的范围相同。
因此,您要删除行scope: { arValidations: '@?' }
但是现在您需要以常规方式手动实施此@
绑定,方法是在link
函数中添加:
attrs.$observe('arValidations', function(value) {
scope.arValidations = value;
});
这样,每次更新{{}}
插值绑定时,都会更新范围。
更新为了让您的直接拥有自己的范围,但仍然继承并且不是孤立的,您需要将scope: true
添加到指令中:
restrict: 'A',
scope: true,
require: '?ngModel',
link: ....