Cordova页面加载触发未打开Modal的ng-repeat脚本执行问题排查
问题原因
Ionic 的 $ionicModal.fromTemplateUrl 方法在初始化阶段,会提前将 Modal 的模板编译并插入到页面 DOM 中,只是默认通过 CSS 设置为隐藏状态。因此 Modal 内的 ng-repeat 和 ng-init 会在 PageA 加载完成后直接执行,完全不等用户点击按钮打开 Modal 的时机。
解决方案
可以从以下几个方向修复问题:
方案1:利用 Modal 的 afterShow 事件触发二维码生成
把二维码生成逻辑移到 Modal 显示完成后的回调中,确保只有 Modal 打开后才执行:
$ionicModal.fromTemplateUrl('ticketModal.html', { scope: $scope, animation: 'slide-in-up', backdrop: 'static', backdropClickToClose:false, focusFirstInput: false }).then(function(modal) { $scope.tixModal = modal; // 监听Modal显示完成事件 modal.addEventListener('afterShow', function() { $scope.genQRCode(); // 手动触发脏检查,确保Angular感知DOM变化 $scope.$apply(); }); });
同时移除 Modal 模板里的 ng-init:
<div ng-repeat="ticket in club.tickets" id="ticketID_{{ticket.ticketID}}"> ... qrCode will be attached here in a <canvas> ... </div>
方案2:用 ng-if 控制 Modal 内容的渲染
在 Modal 的根容器上添加显示状态判断,确保只有 Modal 打开时,内部 DOM 才会被编译渲染:
<!-- Modal根容器添加ng-if --> <div class="modal" ng-if="tixModal.isShown()"> <div ng-repeat="ticket in club.tickets" id="ticketID_{{ticket.ticketID}}" ng-init="$last && genQRCode()"> ... qrCode will be attached here in a <canvas> ... </div> </div>
这种方式能彻底保证 ng-repeat 和 ng-init 只在 Modal 打开时执行。
方案3:在 ng-init 中增加显示状态判断
保留 ng-init,但添加 Modal 显示状态的校验,避免页面加载时执行:
<div ng-repeat="ticket in club.tickets" id="ticketID_{{ticket.ticketID}}" ng-init="$last && tixModal.isShown() && genQRCode()"> ... qrCode will be attached here in a <canvas> ... </div>
不过这种方式可靠性略低,Angular 脏检查可能会在 Modal 隐藏时也触发判断,但能解决当前核心问题。
补充说明
ng-init的设计初衷是初始化局部变量,而非触发业务逻辑,建议尽量避免用它做这类操作。- 操作 DOM 时优先使用 Angular 原生的
angular.element,减少对 jQuery 的直接依赖,避免兼容性问题。
内容的提问来源于stack exchange,提问作者rolinger
相关产品推荐
相关产品推荐

