#angularjs #angularjs-directive #overriding #ngroute
Вопрос:
Я хочу переопределить директиву angularjs во время выполнения в моем одностраничном приложении. Возможно ли это? Это моя первая страница js:
appGML.directive('singleSelectKeyUp', function ($resource, $compile, $parse, $timeout, $http, $document,$q) {
return {
restrict: 'A',
require: 'ngModel',
scope: {
singleSelectKeyUp: '='
},
link: function (scope, element, attr, ngModel) {
return scope.$watch(function () {
return ngModel.$modelValue;
}, function (name) {
console.log('first page');
});
};
});
appGML.controller("Pay_tra_advertisementController", function ($sce, $compile, $timeout, $scope, $uibModal, $parse, $http, Upload, $mdBottomSheet, $q) {//
});
Это моя вторая страница js:
appGML.directive('singleSelectKeyUp', function ($resource, $compile, $parse, $timeout, $http, $document,$q) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attr, ngModel) {
return scope.$watch(function () {
return ngModel.$modelValue;
}, function (name) {
console.log('second page');
});
};
});
appGML.controller("Pro_tra_boqController", function ($q, $compile, $scope, $http, $parse, $uibModal, Upload, $timeout){//
});
но при маршрутизации по ngRoute я открыл две страницы одну за другой, обе директивы находятся в appGML._invokeQueue, и выполняется только первая директива.
appGML.config(function ($provide,$routeProvider, $ocLazyLoadProvider, $locationProvider, $controllerProvider, $compileProvider/*, $urlMatcherFactoryProvider, $stateProvider*//*, $urlRouterProvider*/) {
appGML.controller = $controllerProvider.register;
appGML.directive = $compileProvider.directive;
function loadScript(path) {
var result = $.Deferred(),
script = document.createElement("script");
script.async = "async";
script.type = "text/javascript";
script.src = path;
script.onload = script.onreadystatechange = function (_, isAbort) {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
if (isAbort)
result.reject();
else
result.resolve();
}
};
script.onerror = function () { result.reject(); };
document.querySelector("head").appendChild(script);
return result.promise();
}
function loader(arrayName) {
return {
load: function ($q) {
var deferred = $q.defer(),
map = arrayName.map(function (name) {
return loadScript('/JSController' name ".js");
});
$provide.decorator('singleSelectKeyUpDirective', ['$delegate', function ($delegate) {
//$delegate is array of all ng-click directive
//in this case first one is angular buildin ng-click
//so we remove it.
console.log('load:sskuL', $delegate);
//$delegate.shift();
return $delegate;
}]);
$q.all(map).then(function (r) {
deferred.resolve();
});
return deferred.promise;
}
};
}
$routeProvider.when('/PayModule/Pay_tra_advertisement', {
templateUrl: '/PayModule/Pay_tra_advertisement',
controller: 'Pay_tra_advertisementController',
resolve: loader(['/PayModule/Pay_tra_advertisement'])
})
.when('/ProModule/Pro_tra_boq', {
templateUrl: '/ProModule/Pro_tra_boq',
controller: 'Pro_tra_boqController',
resolve: loader(['/ProModule/Pro_tra_boq'])
})
});
Выход есть
first page
Возможно ли отключить первую директиву и переопределить ее новой директивой?
Заранее спасибо
Ответ №1:
Спасибо, что потратили свое драгоценное время на мои вопросы, друзья. Я преодолеваю это, добавляя вложенные директивы
appGML.config(function ($provide, $routeProvider, $ocLazyLoadProvider, $locationProvider, $controllerProvider, $compileProvider/*, $urlMatcherFactoryProvider, $stateProvider*//*, $urlRouterProvider*/) {
$provide.decorator('$controller', [
'$delegate',
function ($delegate) {
return function (constructor, locals) {
if (typeof constructor == "string") {
locals.$scope.controllerName = constructor;
}
return $delegate.apply(this, [].slice.call(arguments));
}
}]);
//.... other routing codes
});
и это моя директива по гнездованию
appGML.directive('containerDirective', function ($compile,$location) {
return {
restrict: 'AE',
link: function (scope, elem, attrs, ctrl) {
//if (elem.closest('form').attr('id') == 'Advertisementfrm') {
// elem.attr('single-select-key-up-adv', '');
//}
//if (elem.closest('form').attr('id') == 'Boqdiv') {
// elem.attr('single-select-key-up-boq', '');
//}
if (scope.$parent.$parent.$parent.controllerName == 'Pay_tra_advertisementController') {
elem.attr('single-select-key-up-adv', '');
}
if (scope.$parent.$parent.$parent.controllerName == 'Pro_tra_boqController') {
elem.attr('single-select-key-up-boq', '');
}
elem.removeAttr('container-directive');
$compile(elem)(scope);
}
}
})
Затем я переименовал свои вложенные директивы
appGML.directive('singleSelectKeyUpAdv', function ($resource, $compile, $parse, $timeout, $http, $document, $q){
//old code
});
и
appGML.directive('singleSelectKeyUpBoq', function ($resource, $compile, $parse, $timeout, $http, $document) {
//old code
});