pristine form before angularjs javascript-events angularjs-scope

form - pristine angularjs



AngularJS: ¿revertir el formulario en la cancelación modal? (3)

Estoy tratando de usar el nuevo método $rollbackViewValue() AngularJS 1.3.0 en ngModelController para cancelar los cambios a un formulario en un menú emergente modal o persistirlos cuando cierro el modal. Estoy usando BootstrapUI para el servicio $modal .

Creo que estoy en el camino correcto, pero hay algo que no funciona del todo bien:

En mi controlador, tengo:

$scope.updateCharge = function (charge) { var scope = $scope.$new(); scope.charge = charge; var modalInstance = $modal.open({ templateUrl: ''client/app/views/providers/charges/updateCharge.html'', scope: scope }); modalInstance.result.then(function () { scope.charge.$save({providerId: providerId, chargeId: charge.id}); }); };

En mi plantilla, tengo lo siguiente:

<form name="form" novalidate ng-model-options="{updateOn: ''save'', debounce: {''save'': 0 }}" class="form-horizontal" role="form"> <div class="modal-body"> <div class="form-group"> <label class="col-sm-3 control-label" for="chargeName">Name</label> <div class="col-sm-9"> <input type="text" class="form-control" required ng-model="charge.code" id="chargeName"/> </div> </div> </div> <div class="modal-footer"> <button class="btn btn-primary" ng-disabled="form.$invalid" ng-click="form.$broadcast(''save''); $close()">Update</button> <button class="btn btn-warning" ng-click="form.$rollbackViewValue(); $dismiss(''cancel'')">Cancel</button> </div> </form>

En general, esto parece funcionar. Cuando hago clic en cancelar, mis cambios se revierten. Cuando hago clic en Actualizar, el modal se cierra pero no veo mis actualizaciones en el objeto scope.charge .

Hubiera esperado que mi objeto scope.charge fuera actualizado antes del cierre modal.

¿Estoy usando las ng-model-options incorrectamente?

Si agrego un botón ''Aplicar'' por separado que solo muestra un form.$broadcast(''save'') , veo que el objeto de mi alcance está correctamente actualizado. Por lo tanto, supongo que se llama a my $ close () antes de que las ng-model-options procesen el evento. ¿Cómo puedo evitar esta condición de carrera?


Puedo ver algunos problemas con tu código:

  • ngModelOptions.updatedOn está destinado a ser un evento DOM , es decir, hacer clic, desenfocar, mouseenter, mouseover, etc.
  • El controlador de formulario NO tiene un método $broadcast , por lo que nunca emite un evento.

Creo que el hecho de que funcione es porque no hay type="button" en el <button> por lo que se consideran como "submit" dentro del formulario. Y el modelo se actualiza debido a eso.

Le sugiero que use una versión simplificada, y

  • elimine las ng-model-options del formulario.
  • agregue un type="submit" al botón Actualizar y elimine el form.$broadcast
  • agregue un type="button" al botón Cancelar.

No estoy seguro de cómo funcionaría con el modal, pero aquí hay un plunkr con ng-if : http://plnkr.co/edit/m37Fd0NybpnfslNkvJnO


Puede utilizar el método $rollbackViewValue() para revertir los cambios, pero creo que esa no es la intención.

$ rollbackViewValue (); Cancele una actualización y restablezca el valor del elemento de entrada para evitar una actualización de $ modelValue, que puede ser causado por un evento relanzado pendiente o porque la entrada está esperando algún evento futuro.

Si tiene una entrada que utiliza ng-model-options para configurar eventos o eventos con eliminación de rebote como desenfoque, puede tener una situación donde hay un período cuando $ viewValue no está sincronizado con ngModel $ modelValue.

En este caso, puede encontrarse con dificultades si intenta actualizar el $ modelValue de ngModel programmatically antes de que estos eventos eliminados / futuros se hayan resuelto / ocurrido, porque el mecanismo de comprobación sucia de Angular no puede decir si el modelo realmente ha cambiado o no.

Se debe llamar al método $ rollbackViewValue () antes de cambiar programáticamente el modelo de una entrada que puede tener tales eventos pendientes. Esto es importante para asegurarse de que el campo de entrada se actualizará con el nuevo valor del modelo y se cancelarán todas las operaciones pendientes.

El caso de uso normal es copiar el modelo, opcionalmente para mantener el modelo y, si todo está bien, actualizar el modelo.

_this = this; this.edit = function() { this.modelToEdit = angular.copy(this.originalModel); } this.save = function () { service.save(modelToEdit).then(function(savedModel) { _this.originalModel = savedModel; }); }

O puede hacer una backup del modelo y restaurar cuando cancela

_this = this; this.edit = function() { this.backupModel = angular.copy(originalModel); } this.cancel = function() { this.originalModel = this.backupModel; } this.save = function() { service.save(this.originalModel).then(function(data) {}, function(error) { _this.originalModel = _this.backupModel;}) }


No terminé usando ninguna de las opciones sugeridas como respuestas, porque la realidad es que angular 1x no tiene una forma "adecuada" de hacer lo que quiero. Angular usa enlace de 2 vías, y sí puedo escribir directivas de lujo para facilitar la vida, pero de hecho solo hace que el html se vea aún más complicado.

Me conformé con la manera sugerida según muchos hilos en el foro y es utilizar angular.copy y luego usar el modelo clonado en tu html. Cuando envíe cambios, establezca el modelo clonado en el modelo original.

Hubo un montón de ejemplos aquí sobre cómo usar angular.copy. Y funciona bien