Я думаю, что директива ngModel не должна создавать новую область действия, поскольку она должна вносить изменения в переменные родительской области.
Пожалуйста, поправьте меня, если я ошибаюсь.
А также, глядя на источник области действия ngModel, не определен, поэтому он не должен создавать новую область для директивы.
var ngModelDirective = ['$rootScope', function($rootScope) {
return {
restrict: 'A',
require: ['ngModel', '^?form', '^?ngModelOptions'],
controller: NgModelController,
// Prelink needs to run before any input directive
// so that we can set the NgModelOptions in NgModelController
// before anyone else uses it.
priority: 1,
compile: function ngModelCompile(element) {
// Setup initial state of the control
element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);
return {
pre: function ngModelPreLink(scope, element, attr, ctrls) {
var modelCtrl = ctrls[0],
formCtrl = ctrls[1] || modelCtrl.$$parentForm;
modelCtrl.$$setOptions(ctrls[2] && ctrls[2].$options);
// notify others, especially parent forms
formCtrl.$addControl(modelCtrl);
attr.$observe('name', function(newValue) {
if (modelCtrl.$name !== newValue) {
modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);
}
});
scope.$on('$destroy', function() {
modelCtrl.$$parentForm.$removeControl(modelCtrl);
});
},
post: function ngModelPostLink(scope, element, attr, ctrls) {
var modelCtrl = ctrls[0];
if (modelCtrl.$options && modelCtrl.$options.updateOn) {
element.on(modelCtrl.$options.updateOn, function(ev) {
modelCtrl.$$debounceViewValueCommit(ev && ev.type);
});
}
element.on('blur', function() {
if (modelCtrl.$touched) return;
if ($rootScope.$$phase) {
scope.$evalAsync(modelCtrl.$setTouched);
} else {
scope.$apply(modelCtrl.$setTouched);
}
});
}
};
}
};
}];
Также я не понимаю, почему директива ngModel требует самого ngModel.
require: ['ngModel', '^? form', '^? ngModelOptions'] Нельзя ли его игнорировать и писать как
require: ['^? form', '^? ngModelOptions']
Если нет, то объясните, почему?
ngModel не создает изолированную область. Причина ngModel указана в массиве require так, чтобы его контроллер (NgModelController) был введен в функцию связи. Обратите внимание на аргумент ctrls, который передается в функцию ngModelPostLink. Поскольку ngModel указан в массиве, ctrls [0] будет экземпляром NgModelController. ctrls [1] - контроллер формы и т.д.