Angular $templateCache缓存失效:ng-include引用时出现404错误
解决AngularJS $templateCache缓存后ng-include仍报404的问题
这个问题我之前帮不少开发者排查过,核心问题基本都是模板缓存的时机不对或者模块/key匹配出了问题,咱们一步步来定位解决:
1. 最常见原因:缓存操作晚于ng-include的请求时机
你在控制器里执行$templateCache.put,但AngularJS可能在控制器初始化之前就已经尝试加载ng-include指定的模板了——这时候缓存里还没有dqs.html,自然会发起HTTP请求导致404。
解决办法:
方案A:把缓存移到模块的run()块(优先推荐)
run()块是AngularJS启动时最早执行的代码块之一,能确保模板缓存在任何视图请求之前就准备好:
angular.module('你的应用模块名') .run(['$templateCache', function($templateCache) { // 这里传入你的filteredFormHtml,如果是静态/提前生成的内容 $templateCache.put('dqs.html', filteredFormHtml); }]);
方案B:用ng-if延迟ng-include的加载(动态生成HTML的场景)
如果filteredFormHtml必须由控制器动态生成(比如依赖接口数据),那就先让ng-include处于未激活状态,直到缓存完成:
// 你的控制器代码 app.controller('YourController', ['$templateCache', '$scope', function($templateCache, $scope) { // 模拟动态生成HTML的过程 const filteredFormHtml = '<div class="form-content">你的动态表单内容</div>'; // 存入缓存 $templateCache.put('dqs.html', filteredFormHtml); // 标记缓存已就绪,让ng-include开始加载 $scope.isTemplateReady = true; }]);
对应的HTML修改:
<div id="dqs" ng-if="isTemplateReady" ng-include="'dqs.html'" class="form__main" set-height> </div>
2. 检查模块依赖与缓存key的一致性
- 模块依赖问题:如果你的控制器属于子模块(比如
app.myAccount),而$templateCache是在另一个模块里操作的,要确保子模块依赖了包含缓存操作的模块,否则缓存不会共享。 - key严格匹配:AngularJS的
$templateCache对key是大小写敏感的,要确保put的'dqs.html'和ng-include里的'dqs.html'完全一致(比如不要多写斜杠'/dqs.html',也不要大小写错误'DQS.html')。
你可以在控制器里打印缓存内容验证是否存成功:
console.log($templateCache.get('dqs.html')); // 输出undefined说明缓存没存进去
3. 动态异步场景的额外处理
如果filteredFormHtml是通过异步请求生成的(比如从接口拿数据后渲染),要注意:
- 先移除旧的缓存(如果有的话),避免冲突
- 确保在AngularJS的 digest 周期内更新缓存
// 异步生成模板示例 $http.get('/api/form-config').then(function(res) { const filteredFormHtml = processFormConfig(res.data); // 先移除旧缓存,再存入新内容 $templateCache.remove('dqs.html'); $templateCache.put('dqs.html', filteredFormHtml); // 如果是在AngularJS上下文外执行(比如第三方回调),需要手动触发digest if (!$scope.$$phase) { $scope.$apply(); } // 标记模板就绪 $scope.isTemplateReady = true; });
4. 避免预加载模板的覆盖
如果你用了构建工具(比如gulp-angular-templatecache)或者<script type="text/ng-template">预加载了模板,要确保这些预加载的模板key和你动态put的key不重复,或者让动态put操作在预加载之后执行(run块会在预加载之后执行,所以用方案A一般不会有问题)。
内容的提问来源于stack exchange,提问作者Harpreet Singh
相关产品推荐
相关产品推荐

