You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS单页应用运行时覆盖自定义directive指令的实现方案咨询

需求可以实现,以下是具体的原因说明和解决方案:


问题原因

AngularJS默认允许注册多个同名指令,所有注册的指令会按顺序存入数组,默认优先级相同的情况下会依次执行。但你的两个指令都声明了隔离scope,同一个元素上只能有一个隔离scope生效,因此只有首次注册的指令会正常运行,后续注册的会被静默忽略。同时你当前的decorator逻辑没有生效,是因为你未在decorator中移除旧指令,且没有清理AngularJS内置的指令缓存。


可行的解决方案

这里提供两种可直接落地的实现方式:

方案1:手动清理旧指令缓存后注册新指令

在第二页JS代码的最前面添加清理逻辑,清除旧的指令注册记录和缓存后再注册新指令:

// 第二页JS开头添加
appGML.run(function($compile) {
  // 清除AngularJS内置的指令缓存
  delete $compile._directiveCache.singleSelectKeyUp;
  // 移除invokeQueue中旧的同名指令注册记录
  appGML._invokeQueue = appGML._invokeQueue.filter(item => {
    return !(item[0] === '$compileProvider' && item[1] === 'directive' && item[2][0] === 'singleSelectKeyUp');
  });
});

// 后面接你原来的singleSelectKeyUp指令注册代码
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');
        });
    }
};
});

方案2:通过decorator过滤指令数组

调整你路由配置中的decorator逻辑,直接保留最后注册的新指令,移除旧指令:

// 把你原来loader中的decorator替换为以下逻辑,注意要放在脚本加载完成的回调中
$q.all(map).then(function (r) {
  $provide.decorator('singleSelectKeyUpDirective', ['$delegate', function ($delegate) {
    // 只保留最后注册的指令,移除之前的所有旧版本
    return [$delegate.pop()];
  }]);
  deferred.resolve();
});

验证效果

修改完成后依次加载两个页面,控制台会依次输出:

first page
second page

符合预期要求。

内容的提问来源于stack exchange,提问作者Angularjsguy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:48:00