如何在iFrame加载完成后调用AngularJS控制器的init函数
解决方案
核心原理
ng-init 会在DOM元素初始化完成、Angular编译阶段就触发,确实早于iframe的资源加载完成时机。我们需要把init方法的触发逻辑绑定到iframe的原生load事件回调中,等otherFunction执行完成后再调用控制器的init方法。
快速实现方案
- 调整模板中iframe的onload绑定逻辑,删除原来的ng-init触发init的代码
<!-- 原有的ng-init触发init的代码要删掉 --> <iframe src="你的iframe资源地址" onload="handleIframeLoad()"></iframe>
- 定义onload回调函数,执行完原有逻辑后调用控制器的init方法
// 全局作用域下的回调函数 function handleIframeLoad() { // 先执行你原来绑定在onload上的逻辑 otherFunction(); // 获取MainCtrl对应的Angular作用域 const mainScope = angular.element(document.querySelector('[ng-controller="MainCtrl"]')).scope(); // 非Angular上下文内调用作用域方法需要用$apply触发脏检查 mainScope.$apply(() => { mainScope.init(); }); }
推荐的Angular原生实现(无全局函数)
通过自定义指令绑定load事件,逻辑更内聚,符合Angular的编码规范:
- 定义iframe加载事件绑定指令
angular.module('你的应用模块名').directive('iframeLoadDone', function() { return { restrict: 'A', scope: { afterLoad: '&' }, link: function(scope, element) { // 监听iframe的原生load事件 element.on('load', function() { // 先执行原有的onload逻辑 otherFunction(); // 执行传入的回调方法 scope.$apply(() => { scope.afterLoad(); }); }); } } })
- 模板中使用指令
<iframe src="你的iframe资源地址" iframe-load-done after-load="init()"></iframe>
注意事项
- 请删除控制器初始化时直接调用
$scope.init()的代码,避免提前执行 - 如果
otherFunction是iframe内部定义的函数,需要确保iframe和父页面同域,否则会因为跨域限制无法访问iframe内部上下文
内容的提问来源于stack exchange,提问作者RazorUK84
相关产品推荐
相关产品推荐

