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

AngularJS ng-click触发后表格无法加载JSON数据问题

AngularJS 点击表格行加载二级数据失败排查指引

问题表现

  • 标记为*(1)*的首表格数据加载正常,点击行时传入go函数的Account参数取值正确,二级表格容器可正常显示
  • 二级表格内部始终无法渲染对应Account的费用数据

核心错误原因

  • 动态注册Angular组件无效:将dataService服务、customersCtrl2控制器的定义写在了go点击回调内部。AngularJS在页面初始引导完成后,后续动态调用app.service()/app.controller()注册的组件不会被框架识别、初始化,完全无法生效
  • 重复声明ng-app:页面两个容器节点分别声明了ng-app="myApp",AngularJS默认只会自动引导第一个匹配到的ng-app节点,第二个ng-app对应的作用域根本不会被框架接管
  • 异步Promise逻辑错误:$http请求返回的是Promise异步对象,直接将Promise对象赋值给$scope.recds2无法拿到接口返回的业务数据,必须在Promise的then回调中给作用域变量赋值
  • 服务写法不符合规范:服务内未正确暴露getJsonData调用方法,且错误地将$scope注入到服务中(服务是全局单例,不存在作用域概念)
  • 原生DOM操作存在同步问题:直接通过document.getElementById修改元素显隐状态,没有和Angular作用域变量绑定,容易出现视图与数据不同步的问题
  • HTML注释写法错误:代码中<----- data below not produced----->不是合法HTML注释格式,会直接渲染在页面上,正确写法为<!-- 注释内容 -->

修正后实现代码

JS逻辑部分

var app = angular.module('myApp', []);
// 全局注册数据服务,不要放在点击回调内
app.service('dataService', function($http) {
  // 暴露按账号拉取费用数据的方法
  this.getJsonData = function(ac) {
    return $http.get('http://Amanda/Charges.aspx?ac=' + ac).then(function(response) {
      return response.data.records2;
    });
  }
});

// 二级表格控制器,全局注册
app.controller('customersCtrl2', function($scope, dataService) {
  $scope.dataService = dataService;
  $scope.showChargeTable = false;
  $scope.recds2 = [];
});

// 首表格控制器
app.controller('customersCtrl', function($scope, $http) {
  // 加载首表格数据
  $http.get("http://Amanda/test2.aspx")
  .then(function(response) {
    $scope.recds = response.data.records;
  });

  // 行点击逻辑
  $scope.go = function(account) {
    // 通过作用域变量控制表格显隐
    $scope.showChargeTable = true;
    // 调用服务拉取对应账号数据,在回调内赋值
    $scope.dataService.getJsonData(account).then(function(records) {
      $scope.recds2 = records;
    });
  }
});

HTML模板部分

<body style="background-color: #F1FAFA">
  <!-- 整个页面仅声明一次ng-app,包裹所有需要Angular接管的节点 -->
  <div ng-app="myApp" ng-controller="customersCtrl2">
    <!-- 首表格区域 -->
    <div ng-controller="customersCtrl">
      <table id="Summary">
        <tr>
          <th class="auto-style6" style="width: 66px">Annual<br>Ranking<br><span class="auto-style7">(this week)</span></th>
          <th>Account</th>
          <th>Customer</th>
          <th>Cust <br> Status</th>
          <th>% of <br>Annual<br>Revenue</th>
          <th>This week</th>
          <th>week-1</th>
          <th style="width: 71px">week-2</th>
          <th>week-3</th>
          <th>&nbsp;&nbsp; YTD <br>Revenue</th>
          <th>Receipted<br>Loads</th>
          <th>Receipted <br>Pallets</th>
          <th>Delivery <br>Loads</th>
          <th>Delivery<br>Pallets</th>
          <th>Last<br>Agreed £</th>
        </tr>
        <tr ng-repeat="x in recds" ng-click="go(x.Account)">
          <td class="auto-style2" style="width: 66px">{{ x.Position }}<span class="auto-style8"> ({{ x.WPosition }})</span></td>
          <td id="act" class="auto-style2">{{ x.Account }}</td>
          <td class="auto-style2">{{ x.Customer }}</td>
          <td class="auto-style2">{{ x.CType }}</td>
          <td class="auto-style3">{{ x.Perc }}</td>
          <td class="auto-style5">
            <span class="auto-style4">{{ x.ThisWeek}}&nbsp;</span>
            <img ng-src="{{(x.LastWeek - x.ThisWeek) < 0 ? 'Images/green.png' : 'Images/red.png'}}" class="auto-style4" style="float: right">
          </td>
          <td class="auto-style1">
            <span class="auto-style4">{{ x.LastWeek }}&nbsp;</span>
            <img ng-src="{{(x.Week2 - x.LastWeek) < 0 ? 'Images/green.png' : 'Images/red.png'}}" class="auto-style4" style="float: right">
          </td>
          <td class="auto-style1" style="width: 71px">
            <span class="auto-style4">{{ x.Week2 }}&nbsp;</span>
            <img ng-src="{{(x.Week3 - x.Week2) < 0 ? 'Images/green.png' : 'Images/red.png'}}" class="auto-style4" style="float: right">
          </td>
          <td class="auto-style3">{{ x.Week3 }}</td>    
          <td class="auto-style3">{{ x.YTD }}</td>
          <td class="auto-style3">{{ x.recs }}</td>
          <td class="auto-style3">{{ x.recsplt }}</td>
          <td class="auto-style3">{{ x.dels }}</td>
          <td class="auto-style3">{{ x.delsplt }}</td>
          <td id="preview" class="auto-style3">{{ x.preview }}</td>
        </tr>
      </table>
    </div>

    <!-- 二级费用表格区域,通过ng-show控制显隐,无需重复声明ng-app和controller -->
    <div id="div1" class="block2" ng-show="showChargeTable">
      <table id="charge">
        <tr>
          <th>Account</th>
          <th>Chargecode</th>
          <th>Rate</th>
        </tr>
        <!-- 修正非法HTML注释 -->
        <!-- data below not produced -->
        <tr ng-repeat="y in recds2">
          <td>{{ y.Customer }}</td>
          <td>{{ y.ChargeCode }}</td>
          <td>{{ y.Charge }}</td>
        </tr> 
      </table>
    </div>
  </div>
</body>

补充排查点

  • 打开浏览器控制台Network面板,确认点击行时Charges.aspx接口请求正常,无跨域、404/500错误,返回数据结构中确实存在records2数组
  • 确认接口返回的字段名与模板绑定的Customer/ChargeCode/Charge完全一致,Angular模板绑定大小写敏感
  • 如果需要父子控制器完全解耦,可以使用$broadcast/$on做事件通信传递数据,避免作用域嵌套带来的变量污染问题

内容的提问来源于stack exchange,提问作者Robert Bee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:03:40