AngularJS中ng-model绑定firstTT变量未定义致程序失效如何排查
问题排查结论
firstTT未定义的报错是前置脚本执行失败导致的连锁反应,和你在$scope里初始化该变量的操作无关,核心诱因有3个:
- 代码中调用了
moment()相关API,但未引入moment.js依赖,浏览器执行到全局作用域的var dayMillis = moment().diff(moment().startOf('day'));时直接抛出moment is not defined错误,打断整个脚本执行流程,后续Angular模块初始化、控制器注册逻辑完全没运行,所有Angular绑定的变量自然都无法识别。 - 目的地输入框的type属性存在语法错误:原代码写为
<input type = text" ng-model = "dest"/>,漏了type属性值的前引号,HTML解析异常会进一步干扰Angular的编译流程。 - 你注释掉的
console.log(firstTT)写在Angular控制器外部的全局作用域中,就算脚本正常执行,全局作用域下也不存在firstTT变量——这个变量是挂载在控制器$scope上的,仅能在控制器内部、页面受Angular管控的DOM表达式中访问,全局作用域直接调用必然报未定义。
修复方案
按以下顺序调整代码即可解决问题:
- 在所有自定义脚本前引入moment.js依赖,保证时间计算逻辑可以正常运行
- 修正目的地输入框的语法错误,补全type属性的前引号
- 把全局作用域下的时间计算逻辑移到控制器内部,避免全局变量污染和执行顺序问题
- 给表单绑定
ng-submit事件处理提交逻辑,不要在全局作用域访问$scope上的绑定变量 - 给提交按钮绑定的逻辑中,直接通过
$scope.firstTT获取用户输入的首班车时间即可,不需要额外声明全局变量
修复后核心代码示例
<!-- 引入moment依赖 --> <script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script> <body> <div ng-app = "myApp" ng-controller = "myCtrl"> <table> <tr><th>Train Name</th><th>Destination</th><th>Frequency</th><th>Minutes Away</th><th>Next Arrival</th><th></th></tr> <tr ng-repeat="x in trainArray"> <td>{{ x.name }}</td> <td>{{ x.dest }}</td> <td>{{ x.freq }}</td> <td></td> <td></td> <td>X</td> </tr> </table> {{dayMinutes}} <!-- 修正input语法错误,增加ng-submit绑定 --> <form ng-submit="addTrain()"> Train Name: <input type = "text" ng-model = "name"/> <br><br> Destination: <input type="text" ng-model = "dest"/> <br><br> First Train Time: <input type="text" placeholder = "(ex. 08:45 for 8:45pm)" ng-model = "firstTT"> <br><br> Frequency (Minutes): <input type="text" style = "width: 50px;" ng-model = "freq"> <br><br> <input type = "submit" value = "submit" id = "submit" data-toggle = "tool-tip" title = "add train"> </form> </div> <script> var app = angular.module('myApp', []); app.controller('myCtrl', function($scope){ // 时间计算移入控制器 var dayMillis = moment().diff(moment().startOf('day')); $scope.dayMinutes = dayMillis/60000; $scope.firstTT = ""; $scope.trainArray = [ { name: "Thomas", dest: "New York", first: "05:00", freq: 30 }, { name: "Duncan", dest: "Boston", first: "06:00", freq: 45 } ]; // 表单提交逻辑 $scope.addTrain = function(){ // 此处可正常访问$scope.firstTT,不会报未定义 var startMinutes = moment($scope.firstTT, "HH:mm").diff(moment().startOf('day'), 'minutes'); // 后续计算下一班车时间、插入数组的逻辑可在此处补充 $scope.trainArray.push({ name: $scope.name, dest: $scope.dest, first: $scope.firstTT, freq: Number($scope.freq) }) } }) </script> </body> </html>
额外注意:原代码中时间格式占位符写的
hh:mm是12小时制,如果要处理24小时制的列车时刻,建议改成HH:mm避免时间解析错误。
内容的提问来源于stack exchange,提问作者DennisM
相关产品推荐
相关产品推荐

