Angular.js programaticamente definindo um campo de formulário para sujo

Eu estou programaticamente atualizando alguns dos campos no meu formulário com um valor e gostaria de definir o estado do campo para $dirty . Fazendo algo como:

$scope.myForm.username.$dirty = true; parece não funcionar.

Existe um método $setPristine que eu posso usar para redefinir o estado do campo, mas não há um método $setDirty ?

Então, como se faz isso?

Vi esta postagem em https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4, mas não consigo encontrar o método $setDirty . Eu estou usando o Angular versão 1.1.5.

Desde o AngularJS 1.3.4 você pode usar $setDirty() nos campos ( fonte ). Por exemplo, para cada campo com erro e marcado como obrigatório, você pode fazer o seguinte:

 angular.forEach($scope.form.$error.required, function(field) { field.$setDirty(); }); 

No seu caso, $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue); faz o truque – torna a forma e o campo sujos e acrescenta classs CSS apropriadas.

Só para ser honesto, encontrei essa solução em novo post no tópico do link da sua pergunta. Funcionou perfeitamente para mim, então estou colocando isso aqui como uma resposta independente para facilitar a sua descoberta.

EDITAR:

A solução acima funciona melhor para a versão Angular até 1.3.3. Começando com 1.3.4 você deve usar o método de API recém-exposto $setDirty() de ngModel.NgModelController .

você terá que definir manualmente $dirty para true e $pristine para false para o campo. Se você quiser que as classs apareçam na sua input, então você terá que adicionar manualmente ng-dirty e remover ng-pristine classs ng-pristine do elemento. Você pode usar $setDirty() no nível de formulário para fazer tudo isso no próprio formulário, mas não as inputs de formulário, as inputs de formulário não têm atualmente $setDirty() como você mencionou.

Esta resposta pode mudar no futuro, pois eles devem adicionar $setDirty() às inputs, parece lógico.

Se você tem access ao NgModelController (você só pode obter access a ele de uma diretiva), então você pode chamar

 ngModel.$setViewValue("your new view value"); // or to keep the view value the same and just change it to dirty ngModel.$setViewValue(ngModel.$viewValue); 

Feito um jsFiddle só para você que resolve esse problema. simplesmente defina $ dirty para true, mas com um $timeout 0 então ele é executado depois que o DOM foi carregado.

Encontre aqui: JsFiddle

 $timeout(function () { $scope.form.uName.$dirty = true; }, 0); 

Uma function auxiliar para fazer o trabalho:

 function setDirtyForm(form) { angular.forEach(form.$error, function(type) { angular.forEach(type, function(field) { field.$setDirty(); }); }); return form; } 

Isto é o que funcionou para mim

 $scope.form_name.field_name.$setDirty() 

Você pode usar $setDirty(); método. Veja a documentação https://docs.angularjs.org/api/ng/type/form.FormController

Exemplo:

 $scope.myForm.$setDirty(); 

Angular 2

Para quem quer fazer o mesmo em Angular 2, é muito semelhante, além de se apossar da forma

 
Name is required

 import { Component, } from '@angular/core'; import { FormBuilder, Validators } from '@angular/common'; @Component({ selector: 'my-example-form', templateUrl: 'app/my-example-form.component.html', directives: [] }) export class MyFormComponent { myFormModel: any; constructor(private _formBuilder: FormBuilder) { this.myFormModel = this._formBuilder.group({ 'username': ['', Validators.required], 'password': ['', Validators.required] }); } onSubmit() { this.myFormModel.markAsDirty(); for (let control in this.myFormModel.controls) { this.myFormModel.controls[control].markAsDirty(); }; if (this.myFormModel.dirty && this.myFormModel.valid) { // My submit logic } } } 

Nota adicional pequena a resposta @ rmag. Se você tiver campos vazios, mas obrigatórios, que deseja fazer, use:

 $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue !== undefined ? $scope.myForm.username.$viewValue : ''); 

Não sei exatamente por que você está tentando marcar os campos, mas me encontrei em uma situação semelhante porque queria que erros de validação aparecessem quando alguém tentasse enviar um formulário inválido. Acabei usando o jQuery para remover as tags de class .ng-pristine e adicionar tags de class .ng-dirty aos campos apropriados. Por exemplo:

 $scope.submit = function() { // `formName` is the value of the `name` attribute on your `form` tag if (this.formName.$invalid) { $('.ng-invalid:not("form")').each(function() { $(this).removeClass('ng-pristine').addClass('ng-dirty'); }); // the form element itself is index zero, so the first input is typically at index 1 $('.ng-invalid')[1].focus(); } }