AngularJS 1.x控制器无法添加自定义函数问题排查与解决
我的AngularJS弹窗切换按钮排坑记(附Grunt构建踩坑解决)
嘿,刚折腾完一个让我头大的AngularJS问题,跟大家唠唠——我才学AngularJS三周,现在接手一个别人写的非标准结构项目,原开发者失联了。需求很简单:给订阅信息弹窗加两个按钮,切换「订阅详情」和「历史记录」模块,结果写了自定义函数死活没反应,最后居然是Grunt的锅!
先贴我的代码(方便大家对照)
弹窗模板代码
<script type="text/ng-template" id="MobileSubscriptionDetailModal"> <div class="modal-header"> <button type="button" class="close" ng-click="cancel()">×</button> <h4>{{"mobileSubscriptionResource.title"|translate}}</h4><br /> <button ng-click="toggleMobileDetailsInfoHistoryModule()">{{"mobileSubscriptionResource.history"|translate}}</button> <button ng-click="toggleMobileDetailsInfoHistoryModule()">{{"mobileSubscriptionResource.info"|translate}}</button> </div> <div ng-if="showInfoModule" class="modal-body"> <form role="form" name="form" novalidate> </form> </div> <div ng-if="showHistoryModule" ng-include=" 'pages/history.html' "></div> <div class="modal-footer"> <button class="btn btn-primary pull-left" ng-click="edit(mobileSubscription)" ng-show="mobileSubscription.IsOperation">{{'commonResource.edit'|translate}}</button> <button class="btn btn-danger pull-left" ng-click="delete(mobileSubscription)" ng-show="mobileSubscription.IsOperation">{{'commonResource.remove'|translate}}</button> <button class="btn btn-default" ng-click="cancel()" data-translate="commonResource.cancel"></button> </div> </script>
控制器相关代码
app.controller("mobileSubscriptionController", ["$scope", "mobileSubscriptionService", "$rootScope", "$modal", "tools", "statusService", "constantService", "statusFilterService", "columnFilterService", function ($scope, mobileSubscriptionService, $rootScope, $modal, tools, statusService, constantService, statusFilterService, columnFilterService) { $scope.detail = function (mobileSubscription) { var detail = $modal.open({ templateUrl: 'MobileSubscriptionDetailModal', controller: mobileSubscriptionDetailCtrl, backdrop: 'static', resolve: { mobileSubscription: function () { return mobileSubscription; } } }); detail.result.then(function () { initMobileSubscription(); }, function (error) { tools.error(error); }); }; }]); var mobileSubscriptionDetailCtrl = ["$scope", "$rootScope", "$modal", "$modalInstance", "mobileSubscription", "historyService", "tools", function ($scope, $rootScope, $modal, $modalInstance, mobileSubscription, historyService, tools) { $scope.toggleMobileDetailsInfoHistoryModule = function () { alert("inside!"); if ($scope.showInfoModule) { $scope.showHistoryModule = false; } else { $scope.showHistoryModule = true; }; $scope.cancel = function () { $modalInstance.close(); }; }];
遇到的奇葩问题
我当时试了ng-if、ng-show,直接写ng-click="showHistoryModule = !showHistoryModule"居然能生效,但自己写的toggleMobileDetailsInfoHistoryModule函数完全没反应,连弹窗里的$modalInstance.close()也没法通过函数关闭。甚至把函数放到app.factory里也没用,整个人都懵了!
最后发现的罪魁祸首:Grunt构建
偶然瞥见项目根目录的gruntfile.js,我才反应过来——这个项目是用Grunt做构建打包的!我之前修改的都是源码文件,但浏览器加载的是Grunt打包后的压缩/合并文件,我的新代码根本没被编译进去!
解决步骤
- 先全局安装Grunt CLI:
npm install -g grunt-cli(如果没装的话) - 进入项目根目录,安装依赖:
npm install - 运行Grunt构建:看
gruntfile.js里的配置,一般运行grunt build或者直接grunt(默认任务) - 构建完成刷新页面,自定义函数和弹窗关闭功能瞬间正常了!
顺便优化了切换逻辑
后来我也把toggle函数的逻辑改得更清晰,确保两个模块互斥:
$scope.toggleMobileDetailsInfoHistoryModule = function (target) { if (target === 'history') { $scope.showHistoryModule = true; $scope.showInfoModule = false; } else { $scope.showHistoryModule = false; $scope.showInfoModule = true; } };
模板里的按钮也改成传参形式:
<button ng-click="toggleMobileDetailsInfoHistoryModule('history')">{{"mobileSubscriptionResource.history"|translate}}</button> <button ng-click="toggleMobileDetailsInfoHistoryModule('info')">{{"mobileSubscriptionResource.info"|translate}}</button>
这样就不会出现两个模块同时显示或隐藏的情况了。
内容的提问来源于stack exchange,提问作者swedish_junior_dev
相关产品推荐
相关产品推荐

