AngularJS中<td>元素内ng-disabled失效问题求助
看起来你遇到的问题是自定义验证器的状态明明正确变化了,但提交按钮的ng-disabled却没跟着响应对吧?我帮你排查了几个常见的坑,应该能解决问题:
1. 先修复不合法的HTML结构
你的表单里直接嵌套了<td>标签,这不符合HTML规范——<td>必须放在<tr>里,而<tr>又得包裹在<table>中。浏览器遇到这种不合法结构时,会自动调整DOM树,导致表单控制器newform和按钮、输入控件的关联被破坏,按钮自然无法正确读取newform.$invalid的值。
修复后的结构应该是这样的:
<form name="newform"> <div> Form is valid: {{newform.$valid}} </div> <table> <tr> <td> <input type="submit" ng-disabled="newform.$invalid" class="btn btn-primary" ng-click="saveNew()" value="Submit" /> <button class="btn btn-default" ng-click="cancelNew()">Cancel</button> </td> <td> <input required rtp-unique-weather-setting type="number" ng-model="newSetting[fromProp]" name="newSettingFrom" /> </td> <td> <input required type="number" ng-model="newSetting[rankProp]" name="newSettingRank" /> </td> </tr> </table> </form>
2. 让验证器在数据源变化时重新运行
你的验证器现在只在输入值变化时触发,但如果denormalizedSettingsObject.settings这个数据源发生变化(比如新增/删除了设置),当前输入的值可能突然变得重复,但验证器不会自动重新检查。这会导致控件的$invalid状态没有及时更新,进而影响表单状态和按钮的禁用状态。
你可以在指令的link函数里添加一个监听,当数据源变化时手动触发验证:
require('./_index') .directive('rtpUniqueWeatherSetting', function() { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attr, ngModelController) { // 监听数据源变化,重新触发验证 scope.$watchCollection('denormalizedSettingsObject.settings', function() { ngModelController.$validate(); }); var findSetting = function(fromVal) { return scope.denormalizedSettingsObject.settings.find(function(setting) { return setting.from === fromVal; }); }; ngModelController.$validators.uniqueSetting = function(modelValue, viewValue) { var value = modelValue || viewValue; if (!value) return true; // 空值交给required指令处理,避免逻辑冲突 var existing = findSetting(value); if (existing) { console.log('An override starting at ' + value + ' already exists.'); return false; } console.log('Overrides are unique.'); return true; }; } }; });
我还加了if (!value) return true的判断,把空值的验证交给内置的required指令处理,避免自定义验证和内置逻辑冲突。
3. 验证表单控制器的绑定状态
你可以在页面上临时添加{{newform.newSettingFrom.$invalid}}来确认单个输入控件的验证状态是否正确绑定到表单上。如果这个值能正确变化,但{{newform.$valid}}没反应,那大概率还是HTML结构的问题导致表单没正确收集控件状态。
内容的提问来源于stack exchange,提问作者pvgdev
相关产品推荐
相关产品推荐

