You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()">&times;</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打包后的压缩/合并文件,我的新代码根本没被编译进去!

解决步骤

  1. 先全局安装Grunt CLI:npm install -g grunt-cli(如果没装的话)
  2. 进入项目根目录,安装依赖:npm install
  3. 运行Grunt构建:看gruntfile.js里的配置,一般运行grunt build或者直接grunt(默认任务)
  4. 构建完成刷新页面,自定义函数和弹窗关闭功能瞬间正常了!

顺便优化了切换逻辑

后来我也把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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:57:10