【发布时间】:2014-01-21 09:14:57
【问题描述】:
我需要一种方法来遍历 AngularJS 表单的注册控件。本质上,我试图获取所有 $dirty 控件,但没有控件数组(FormController 除了包含控件本身之外,还有许多不同的属性/功能 - 每个都是它自己的对象)。
我一直在查看源代码,发现 FormController 中有一个 controls 数组,这正是我要查找的数组。有没有办法访问这个值,或者扩展 FormController 以包含一个返回这个 controls 数组的函数?
编辑:Plnkr 演示
另外,我意识到从技术上讲,我可以检查密钥字符串中的第一个字符是否为“$”,但我想避免这种情况,以防 FormController/directive 在未来版本的 Angular 中发生变化。
编辑 2:另一个澄清:我的目标是能够确定哪些特定字段是 $dirty,是否通过循环遍历整个控件列表(不包括 $dirty、$invalid、$error、 $name,以及其他存在于 Form 对象中的属性)或通过扩展 FormController 并创建一个函数,该函数仅返回当前脏的控件(并且不等于它们的起始值)
编辑 3:我正在寻找的解决方案需要适用于不同结构的表单/模型。示波器上的模型是通过 AJAX 生成的,因此它们的结构已经设置好(我想避免为我已经通过 AJAX 接收的所有数据硬编码一个新结构)。此外,我希望在多个表单/模型中使用此表单提交过程,并且每个表单/模型都有不同的 JSON 结构——因为它们适用于我们的对象模型中的不同实体。这就是为什么我选择寻求一种方法来访问 FormController 中的controls 对象(我将在下面发布来自FormController 的代码),因为它是唯一可以获得平面数组的地方我所有的领域。
function FormController(element, attrs) {
var form = this,
parentForm = element.parent().controller('form') || nullFormCtrl,
invalidCount = 0, // used to easily determine if we are valid
errors = form.$error = {},
controls = [];
// init state
form.$name = attrs.name || attrs.ngForm;
form.$dirty = false;
form.$pristine = true;
form.$valid = true;
form.$invalid = false;
parentForm.$addControl(form);
// Setup initial state of the control
element.addClass(PRISTINE_CLASS);
toggleValidCss(true);
// convenience method for easy toggling of classes
function toggleValidCss(isValid, validationErrorKey) {
validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
element.
removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey).
addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
}
/**
* @ngdoc function
* @name ng.directive:form.FormController#$addControl
* @methodOf ng.directive:form.FormController
*
* @description
* Register a control with the form.
*
* Input elements using ngModelController do this automatically when they are linked.
*/
form.$addControl = function(control) {
controls.push(control);
if (control.$name && !form.hasOwnProperty(control.$name)) {
form[control.$name] = control;
}
};
/**
* @ngdoc function
* @name ng.directive:form.FormController#$removeControl
* @methodOf ng.directive:form.FormController
*
* @description
* Deregister a control from the form.
*
* Input elements using ngModelController do this automatically when they are destroyed.
*/
form.$removeControl = function(control) {
if (control.$name && form[control.$name] === control) {
delete form[control.$name];
}
forEach(errors, function(queue, validationToken) {
form.$setValidity(validationToken, true, control);
});
arrayRemove(controls, control);
};
// Removed extra code
}
如您所见,表单本身具有私有可用的controls 数组。我想知道是否有办法扩展FormController,以便我可以公开该对象?或者创建一个公共函数,以便我至少可以查看私有数组?
【问题讨论】:
-
您没有与控件关联的模型吗?您可以只观察模型以查看它们是否已更改,而不是循环浏览表单控件。
-
我确实有模型,我也只是想避免做手表,因为 Form 指令中已经有手表来处理所有脏检查,对于大型表单,这可能会执行得很慢:(
-
很好的问题,这与我正在寻找的相同(我的目标是在第一个错误显示后停止提交验证)。这段时间,您是否找到了比检查第一个字符 ($) 更好的替代解决方案?
-
不幸的是,我仍在使用它来检查。如果我找到更好的方法,我会更新帖子。
标签: javascript angularjs angularjs-directive angularjs-ng-form