Почему форма не определена внутри ng-include при проверке $ pristine или $ setDirty ()?
Следующий код выдает ошибку «Ошибка типа: невозможно прочитать свойство« $ pristine »неопределенного», когда я нажимаю кнопку «Проверить».
app.controller('MainCtrl', function($scope) {
// other stuff
})
.controller('Ctrl2', function($scope) {
$scope.product = {description:'pump'};
$scope.output = 'unknown';
// uncomment to avoid undefined error, still can't see $pristine
// $scope.formHolder = {};
$scope.checkForm = function() {
$scope.descriptionTest = $scope.product.description;
if ($scope.formHolder.productForm.$pristine) {
$scope.output = 'yes';
}
if ($scope.formHolder.productForm.$dirty) {
$scope.output = 'no'
}
}
});
HTML
<body ng-controller="MainCtrl">
<div >
<ng-include ng-controller="Ctrl2" src="'myForm.html'"></ng-include>
</div>
</body>
myForm.html
<form name="productForm" novalidate>
<h2>myForm</h2>
description: <input type="text" name="description" ng-model="product.description"/>
<br>
<button ng-click="checkForm()">Check Form</button>
<br>
Form Pristine: {{output}}
<br><br>
I can see the description: {{descriptionTest}}
</form>
Проблема в том, что мой Ctrl2 не видит productForm. Сначала я подумал, что это связано с прототипным наследованием, которое делает ng-include при создании дочерней области, поэтому я попытался добавить переменную в Ctrl2:
$scope.productForm = {};
Это избавило от ошибки, но мой контроллер все еще не правильно видел $ нетронутый или $ грязный.
Наконец-то я заработал, добавив объект $ scope.formHolder над productForm:
.controller('Ctrl2', function($scope) {
$scope.product = {description:'pump'};
$scope.output = 'unknown';
// uncomment to avoid undefined error, still can't see $pristine
$scope.formHolder = {};
$scope.checkForm = function() {
$scope.descriptionTest = $scope.product.description;
if ($scope.formHolder.productForm.$pristine) {
$scope.output = 'yes';
}
if ($scope.formHolder.productForm.$dirty) {
$scope.output = 'no'
}
}
});
HTML
<form name="formHolder.productForm" novalidate>
Почему это работает? И есть ли лучший способ сделать это?
Я закончил таким образом, потому что у меня была рабочая форма и контроллер / шаблон, который я хотел использовать где-то еще. Вероятно, мне следовало бы сделать директиву, но все работало нормально, кроме $ pristine и $ dirty функций формы - все переменные ng-модели были переданы правильно.
Как я могу установить форму, содержащуюся в ng-include, чтобы быть prestine? есть ответ, который «нарушает все правила», но кажется более сложным.
Когда я пишу, когда контроллер формы добавляет $ pristine в область действия и в какую область?
Редактировать / Ответить:
Мой первоначальный вопрос может быть сведен к путанице относительно того, как директива формы записывает в область видимости. У меня было впечатление, что это займет
<form name="productForm">...
и добавить свойства к нему, как
$scope.productForm.$pristine = function() {...}
однако, он пишет прямо поверх productForm:
$scope.productForm = formObject;
Таким образом, объект формы хранится в дочернем, а не родительском объекте, как объяснено в выбранном ответе.
Ключевой самородок в наследовании дочернего контекста, который мне помог, заключается в том, что с цепочкой обращаются при чтении, а не при записи. Поэтому, если вы установите что-то вроде childScope.myThing.property = '123', тогда как это выглядит как запись, сначала нужно выполнить чтение, чтобы узнать, что такое myThing. Принимая во внимание, что установка childScope.myThing = '567' является прямой записью и вообще не предполагает просмотра родительской цепочки. Это все лучше объясняется в:Каковы нюансы объема прототипного / прототипического наследования в AngularJS?