AngularJS中$scope.policyNumber无法显示的问题求助
问题背景
我在AngularJS里定义了$scope.policyNumber,它存储的是从JSON响应里拿到的某个key对应的value,想在下面这段HTML警告框里显示这个值:
<div id="alert_failure" class="alert alert-danger alert-dismissible" role="alert" style="display: none;"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">×</span> </button> <strong>Snap!</strong> SourceID/s {{policyNumber}} is/are already present in OVERRIDE table. </div>
但现在UI只显示Snap! SourceID/s is/are already present in OVERRIDE table.,完全没把policyNumber的值渲染出来。对应的JS提交函数是这样的:
$scope.submit = function(employees) { $http({ 'url' : '/updateOverride', 'method' : 'POST', 'headers' : { 'Content-Type' : 'application/json' }, 'data' : $scope.employees }).then(function(employees) { $scope.insertResult = employees.data; var controllerMessage = $scope.insertResult; var messageKey = 'result'; var result = controllerMessage[messageKey]; console.log(controllerMessage); if(result == "success"){ } else { var dataKey = 'data'; var policyData = controllerMessage[dataKey]; $scope.policyNumber = policyData; console.log($scope.policyNumber); } $("#alert_"+result).show() }) };
请问怎么才能让policyNumber在警告框里正常显示出来?
问题分析与解决方案
别急,我帮你排查下问题,大概率是AngularJS的脏检查机制没触发导致的。你看,你是用jQuery的$("#alert_"+result).show()直接操作DOM显示警告框,但这时候$scope.policyNumber的赋值可能还没被Angular的脏检查监听到,所以模板里的{{policyNumber}}没来得及渲染。
给你几个可行的解决办法:
方法1:用$apply手动触发脏检查
在给$scope.policyNumber赋值之后,调用$scope.$apply()强制Angular更新视图。修改你的else代码块:
else { var dataKey = 'data'; var policyData = controllerMessage[dataKey]; $scope.policyNumber = policyData; console.log($scope.policyNumber); // 手动触发脏检查,避免重复触发的情况 if (!$scope.$$phase) { $scope.$apply(); } }
然后再显示警告框。这样Angular会重新扫描scope的变化,把新的policyNumber值渲染到模板里。
方法2:用Angular的ng-show代替jQuery操作DOM
既然用了Angular,尽量避免直接用jQuery操作DOM,改用Angular的指令来控制显示隐藏,这样能自动触发脏检查,也是更符合Angular最佳实践的做法。
首先修改HTML,给警告框加上ng-show="showFailureAlert":
<div id="alert_failure" class="alert alert-danger alert-dismissible" role="alert" ng-show="showFailureAlert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">×</span> </button> <strong>Snap!</strong> SourceID/s {{policyNumber}} is/are already present in OVERRIDE table. </div>
然后修改JS代码,去掉jQuery的show(),改成设置scope变量:
if(result == "success"){ // 如果有成功的提示框,也可以用类似的ng-show控制 $scope.showSuccessAlert = true; $scope.showFailureAlert = false; } else { var dataKey = 'data'; var policyData = controllerMessage[dataKey]; $scope.policyNumber = policyData; console.log($scope.policyNumber); $scope.showFailureAlert = true; $scope.showSuccessAlert = false; }
这样Angular会在scope变量变化时自动更新视图,policyNumber自然就能正常显示了。
方法3:检查policyData的类型
另外,你可以先确认下policyData是不是一个有效的值——比如会不会是对象或者数组?如果是数组的话,模板里可以改成{{policyNumber.join(', ')}}来把数组转成逗号分隔的字符串,这样显示更友好。比如如果policyData是["ABC123", "DEF456"],模板里用{{policyNumber.join(', ')}}就会显示成ABC123, DEF456。
总结
优先推荐方法2,因为它遵循了Angular的数据驱动视图的理念,减少手动DOM操作带来的问题。如果暂时不想改DOM操作的话,方法1也能快速解决问题。另外别忘了确认policyData的格式是否符合你的显示需求哦。
内容的提问来源于stack exchange,提问作者Mike

