page javascript angularjs web-component

javascript - page - Pasando la forma al componente AngularJS para validación



ng-bind-html-unsafe (2)

Estoy trasladando mi base de código heredado a la nueva arquitectura de componentes promovida con AngularJS 1.5. Encontré un problema al hacer esto para formularios más grandes. Tradicionalmente, adjuntaría la validación del formulario de la siguiente manera:

<form name="myForm"> <input type="text" name="input1" ng-model="vm.input1" required /> <div ng-messages="myForm.input1.$error"> <div ng-message="required">Please fill out this field.</div> </div> <!-- many more inputs --> </form>

Al realizar la transición a una arquitectura de componente, tengo que pasar explícitamente el formulario al componente:

<form name="vm.myForm"> <my-awesome-input-component model="vm.input1" form="vm.myForm"><my-awesome-input-component> <!-- many more inputs --> </form>

Me gustaría evitar contaminar la vm con mi formulario. ¿Hay una mejor manera de lograr la arquitectura de componentes deseada para las formas?


Aquí hay otro enfoque que algunos pueden encontrar útil. Use require para incluir el form padres en su $ctrl :

angular.module("myApp") .component("myInput",{ templateUrl:''path/to/template.html'' bindings:{ myInputModel:''<'', onUpdate:''&'' }, controller: MyInputController, require: { form: ''^form'' } }

En la plantilla de entrada:

<input type="text" name="myInput" ng-model="$ctrl.myInputModel" ng-change="$ctrl.update($ctrl.myInputModel)" required /> <div ng-messages="$ctrl.form.myInput.$error"> <div ng-message="required">Please fill out this field.</div> </div>

No es necesario que pase el formulario explícitamente a su componente, ya que el form se agrega automáticamente a su $ctrl :

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> <my-input my-input-model="ctrl.anyModelIWant" on-update="ctrl.updateMyInput(value)"></my-input> <button type="submit">Some button</button> </form>

Supongo que técnicamente todavía estás contaminando tu máquina virtual, pero al menos no tienes que transmitirla explícitamente a través de tu jerarquía.

Adición de texto para satisfacer el requisito de edición de 6 caracteres, se cambió el período a coma para corregir el ejemplo. Período es confuso para los recién llegados.


Actualización: cambio de nombre de formulario a formulario de referencia , ya que no era explícito que estuviéramos pasando la referencia de formulario real y no solo el nombre del formulario. Esto puede llamarse como quieras, solo ten en claro lo que realmente es.

Como dice el comentario de Iain Reid, no necesita usar vm para esto. Simplemente nombre el formulario como desee y luego le pasa ese nombre a su componente, para que se vea así:

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> <my-input form-reference="myForm"></my-input> <button type="submit">Some button</button> </form>

Asegúrate de escribir "novalidate" en tu formulario para deshabilitar las validaciones predeterminadas del navegador, si quieres manejar las validaciones por tu cuenta (lo cual, según tu uso de ng-messages, creo que haces).

Entonces desde allí, en mi componente escribiría algo como:

angular.module("myApp") .component("myInput",{ templateUrl:''path/to/template.html'' bindings:{ formReference:''<'', myInputModel:''<'', onUpdate:''&'' }, controller: MyInputController }

Y luego en la plantilla de entrada:

<input type="text" name="myInput" ng-model="$ctrl.myInputModel" ng-change="$ctrl.update($ctrl.myInputModel)" required /> <div ng-messages="$ctrl.formReference.myInput.$error"> <div ng-message="required">Please fill out this field.</div> </div>

Algunas notas adicionales sobre los enlaces y cómo pasar y actualizar los modelos:

  • ''<'' : significa vinculante de una manera, que Angular dice que se utilizará para todos los componentes a partir de ahora. Para actualizar el valor y tener enlace de dos vías, debemos incluir una función "onUpdate".
  • onUpdate: ''&'' lo que estoy diciendo aquí es que pasaré una función para actualizar el modelo (una devolución de llamada para eventos de componentes).

Así que en el controlador de entrada escribiría algo como:

function MyInputController(){ var ctrl = this; ctrl.update = function(value){ ctrl.onUpdate({value: value}); }; }

Y, finalmente, cuando uso mi componente dentro de un formulario:

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> <my-input form-reference="myForm" my-input-model="ctrl.anyModelIWant" on-update="ctrl.updateMyInput(value)"></my-input> <button type="submit">Some button</button> </form>

Y el controlador del formulario tendría una función:

... ctrl.updateMyInput = function(value){ ctrl.anyModelIWant = value; } ...

Documentos oficiales: https://docs.angularjs.org/guide/component

Espero que todo esto ayude a alguien :-)