Мне нужен способ перебора зарегистрированных элементов управления формы AngularJS. По сути, я пытаюсь получить все элементы управления $dirty, но массива элементов управления нет (у FormController есть ряд различных свойств/функций в дополнение к содержанию самих элементов управления - каждый как собственный объект).
Я просматривал исходный код и вижу, что в FormController есть массив controls
, который является именно тем массивом, который я ищу. Есть ли способ получить доступ к этому значению или расширить FormController, включив в него функцию, которая возвращает этот массив controls
?
Изменить: Plnkr демо
Кроме того, я понял, что технически я могу проверить первый символ в ключевой строке на «$», но я хотел бы избежать этого в случае изменения FormController/директивы в будущей версии Angular.
Редактировать 2: Еще одно уточнение: моя цель во всем этом - определить, какие конкретные поля являются $ грязными, будь то путем перебора всего списка элементов управления (не включая $ грязный, $ недействительный, $ ошибка, $ имя, и другие свойства, которые живут в объекте формы как есть) или путем расширения FormController и создания функции, которая возвращает только те элементы управления, которые в настоящее время являются грязными (и не равны их начальным значениям).
Редактировать 3: решение, которое я ищу, должно быть применимо к формам/моделям различных структур. Модели в области генерируются с помощью AJAX, поэтому их структура уже установлена (я хотел бы избежать необходимости жесткого кодирования новой структуры для всех данных, которые я уже получаю через AJAX). Кроме того, я хочу использовать этот процесс отправки формы в нескольких формах/моделях, и каждая из них имеет разные структуры JSON, поскольку они применяются к разным объектам в нашей объектной модели. Вот почему я решил спросить способ получить доступ к объекту controls
в FormController (я опубликую код из 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
, чтобы я мог сделать этот объект общедоступным? Или создать общедоступную функцию, чтобы я мог хотя бы просмотреть частный массив?