Issue
I want to override angularjs directive at runtime in my single page application. Is it possible? This is my first page 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) {//
});
This is my secondpage 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){//
});
but while routing by ngRoute, I opened two pages one by one, Both directives are in appGML._invokeQueue, and only first directive is executed.
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'])
})
});
Output is
first page
Is it feasible to disable first directive and override it with new directive? Thanks in advance
Solution
Thanks for spending your valuable time for my question mates. I overcome this by adding nested directives
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
});
and this is my nesting directive
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);
}
}
})
Then I renamed my nested directives
appGML.directive('singleSelectKeyUpAdv', function ($resource, $compile, $parse, $timeout, $http, $document, $q){
//old code
});
and
appGML.directive('singleSelectKeyUpBoq', function ($resource, $compile, $parse, $timeout, $http, $document) {
//old code
});
Answered By - Angularjsguy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.