如何在AngularJS应用的head标签中注入ng-bind实现动态内容
解决AngularJS中动态向head插入REST获取内容的问题
我太懂你遇到的这个坑了——在head标签里用ng-bind-html绑定根作用域变量完全没效果,但换去页面其他区域就正常,这确实和Angular的加载编译时机脱不了干系。head部分在Angular完成初始化前就已经被浏览器解析渲染完了,ng-bind-html指令在这里根本没机会被Angular正确触发执行。
给你几个实用的解决方案:
方案一:用$compile手动编译head内容
如果返回的内容里包含Angular指令,就需要手动编译后再插入head。步骤大概是这样:
app.controller('MainCtrl', function($scope, $http, $compile, $sce) { $http.get('你的REST接口地址').then(function(response) { // 先标记内容为安全HTML,避免Angular的安全拦截 var trustedHtml = $sce.trustAsHtml(response.data); // 获取head元素 var head = angular.element(document.querySelector('head')); // 创建临时承载元素 var tempElement = angular.element('<div ng-bind-html="trustedHead"></div>'); // 把信任后的内容绑定到作用域 $scope.trustedHead = trustedHtml; // 编译元素并关联当前作用域 var compiledElement = $compile(tempElement)($scope); // 把编译后的内容插入head head.append(compiledElement.html()); }); });
方案二:直接操作DOM插入(简单粗暴版)
如果返回的只是静态的link、script这类标签,完全不用编译,直接插入就行:
app.controller('MainCtrl', function($scope, $http, $sce) { $http.get('你的REST接口地址').then(function(response) { var trustedHtml = $sce.trustAsHtml(response.data); // 直接把安全后的HTML插入head末尾 document.querySelector('head').insertAdjacentHTML('beforeend', $sce.getTrustedHtml(trustedHtml)); }); });
方案三:自定义指令处理(更符合Angular思想)
写一个专属指令来处理head的动态内容,以后复用也方便:
app.directive('dynamicHead', function($sce, $compile) { return { restrict: 'A', scope: { content: '=' }, link: function(scope, element) { // 监听内容变化,实时更新head scope.$watch('content', function(newContent) { if (newContent) { var trustedContent = $sce.trustAsHtml(newContent); var compiledContent = $compile(angular.element(trustedContent))(scope.$parent); element.append(compiledContent); } }); } }; });
然后在head标签里直接用这个指令:
<head dynamic-head content="head"></head>
控制器里正常获取REST数据赋值给$scope.head就好。
不管用哪种方案,记得一定要用$sce.trustAsHtml标记内容为安全,不然Angular会因为安全策略直接拦截掉你的HTML内容哦。
内容的提问来源于stack exchange,提问作者Juan Medina
相关产品推荐
相关产品推荐

