在运行时覆盖 angularjs 指令
Overriding angularjs directive at runtime
我想在运行时在我的单页应用程序中覆盖 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
禁用第一个指令并用新指令覆盖它是否可行?
提前致谢
感谢您花费宝贵的时间回答我的问题。
我通过添加嵌套指令
克服了这个问题
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
});
我想在运行时在我的单页应用程序中覆盖 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
禁用第一个指令并用新指令覆盖它是否可行? 提前致谢
感谢您花费宝贵的时间回答我的问题。 我通过添加嵌套指令
克服了这个问题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
});