Il seguente codice genera l'errore "TypeError: Impossibile leggere la proprietà '$ pristine' of undefined" quando faccio clic sul pulsante "check".
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>
Il problema è che il mio Ctrl2 non può vedere il ProductForm. In un primo momento ho pensato che questo avesse a che fare con il prototipo ereditare che ng-includere fa quando si fa un ambito figlio, così ho provato ad aggiungere una variabile in Ctrl2:
$scope.productForm = {};
Questa è sbarazzato dell'errore, ma il mio controller ancora non vedevo correttamente $ pristine o $ dirty.
ho finalmente capito di lavoro con l'aggiunta di un oggetto scope.formHolder $ al di sopra del 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>
Perché fa questo lavoro? E c'è un modo migliore per farlo?
Ho finito in questo modo perché ho avuto una forma & regolatore/modello di lavoro che ho voluto riutilizzare qualche altra parte. Probabilmente dovrei fare una direttiva, ma tutto ha funzionato bene tranne le caratteristiche $ pristine e $ dirty del modulo - tutte le vars ng-model sono state passate correttamente.
How can I set a form contained inside a ng-include to be prestine? ha una risposta che "infrange tutte le regole" ma sembra più complicato.
Quando scrivo quando il modulo Controller aggiunge $ pristine all'ambito e a quale scopo?
Modifica/Risposta:
La mia domanda iniziale può essere riassunta in confusione su come la direttiva modulo scrive al campo di applicazione. Ho avuto l'impressione che ci vorrebbe la cosa in
<form name="productForm">...
e aggiungere proprietà ad esso, come
$scope.productForm.$pristine = function() {...}
tuttavia, scrive direttamente sulla parte superiore del ProductForm:
$scope.productForm = formObject;
Così , l'oggetto modulo è memorizzato nel bambino e non il genitore come spiegato nella risposta selezionata.
L'insieme di chiavi nell'eredità di ambito figlio che mi ha aiutato è che la catena viene consultata in lettura, ma non in scrittura. Quindi, se imposti qualcosa come childScope.myThing.property = '123', mentre sembra una scrittura, prima deve fare una lettura per scoprire cosa è myThing. Considerando che l'impostazione childScope.myThing = '567' è una scrittura diretta e non implica affatto l'osservazione della catena principale. Tutto ciò è spiegato meglio in: What are the nuances of scope prototypal/prototypical inheritance in AngularJS?
In angularJS è chiamata notazione a proposito. – Walfrat