Como faço para verificar corretamente o formulário de validade dentro de um observador quando o modelo de dados é alterado fora da forma em angularjs?
-
21-12-2019 - |
Pergunta
Eu ainda sou muito novo para AngularJS e eu acho que eu estou tendo dificuldade de entender o tempo, com us $escopo.Em um controlador, eu instalação de um observador para algum modelo de dados que está vinculado a vários elementos de formulário.O observador dispara uma solicitação ajax quando as alterações de dados, exceto se o formulário não é válido.Eu estou verificando o formulário de validade com myForm.$válida.Tudo isso é muito para a frente, no entanto, exceto quando o modelo de dados é atualizado no controlador, e não a forma.As validações é executado conforme o esperado, mas formulário.$válido ainda tem o valor anterior, não o que deve ser com os dados atualizados.Por exemplo, se o formulário foi anteriormente válida, em seguida, excluir o modelo de valor vinculado a uma entrada necessária, o observador irá fogo, porque o modelo de dados foi alterado, mas quando eu registrar o valor da myForm.$válido é o valor ainda é verdade, mesmo que ele deve ser falso.
Então, minha pergunta é: A.por que isso está acontecendo?, mas o mais importante B.qual é a maneira correta de lidar com o que eu estou tentando realizar?Seria uma directiva personalizado faz sentido?
Aqui está um exemplo simplificado.
HTML:
<div ng-controller="MyCtrl">
<form name="myForm">
<input type="text" name="myField" ng-model="myData" required>
<button type="button" ng-click="myData=''">Delete</button>
</form>
<div>
The watcher says the form is: <strong>{{ formStatus }}</strong>
</div>
</div>
Controlador:
myApp.controller('MyCtrl', ['$scope', function($scope) {
$scope.myData = 'abc';
$scope.formStatus = '';
$scope.$watch('myData', function(newVal, oldVal) {
if (newVal != oldVal) {
console.log("my data changed");
console.log("my form valid = ", $scope.myForm.$valid);
$scope.formStatus = $scope.myForm.$valid ? 'Valid' : 'Invalid';
}
});
}]);
Solução
Um personalizado directiva é o caminho certo a seguir.É geralmente recomendado para um punhado de razões que os relógios de ser colocado em directivas vs controladores.Em um alto nível, uma razão é que Angulares recomenda controladores de ser fina e só funcionam como uma cola entre o ver e serviços.Mas você está atingindo um específico, interessantes razão.
Controladores de executar antes Angular directivas estão ligadas.Portanto, o seu controlador de assistir é adicionado à lista de observação antes Angular do ngModelWatch()
não para myData
. ngModelWatch()
é onde Angular é executado $formatters
(lembrando que $formatters
, entre outras coisas, são casos em que a avaliação é acionado quando uma mudança acontece para o modelo).
Desde relógios são executados na ordem em que foram adicionados à lista de observação, a sua controlador de $watch
executa antes de validação sendo feito por $formatters
.
Se você em vez disso, coloque o mesmo $watch
dentro de uma directiva que vai ser adicionado durante a ligação após a ngModelWatch()
foi adicionado à lista de observação.Assim, a directiva $watch
irá executar após a validação está feito.
Aqui atualizado um violino onde você pode assistir a ordem de execução de $formatters
e a cada $watch
.E você vai ver a directiva versão funciona como esperado após a execução $formatters
.