将表单传递给AngularJS组件进行验证

时间:2016-05-02 11:11:08

标签: javascript angularjs web-component

我将遗留代码库移动到使用AngularJS 1.5推广的新组件架构。我在为更大的表单执行此操作时遇到了问题。传统上,我会附上表格验证如下:

<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>

转换到组件体系结构时,我必须将表单显式传递给组件:

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

我想避免用我的表单污染vm。有没有更好的方法来实现表单所需的组件架构?

2 个答案:

答案 0 :(得分:21)

更新 - 将表单名称更改为表单引用,因为我们没有明确表示我们传递的是实际的表单引用,而不仅仅是名称表格。这可以随意调用,只要清楚它实际上是什么。

正如Iain Reid的评论所说,你不需要使用vm。您只需将表单命名为您想要的任何名称,然后将该名称传递给您的组件,因此它看起来像这样:

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

如果您想自己处理验证(通过使用我认为您使用的ng-messages),请确保在表单中写入“novalidate”以禁用默认浏览器验证。

然后从那里,在我的组件上,我会写一些像:

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

然后在输入模板中:

<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>

关于绑定的一些额外说明以及如何传递和更新模型:

  • '&lt;':表示单向绑定,Angular称其可用于所有人 从现在开始的组件。为了更新价值并有两种方式 绑定,我们需要包含一个“onUpdate”函数。
  • onUpdate:'&amp;'我在这里说的是我将通过 函数来更新模型(组件事件的回调)。

所以在输入控制器中我会写一些类似的东西:

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

最后,当我在表单中使用我的组件时:

<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>

表单的控制器将具有以下功能:

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

官方文档:https://docs.angularjs.org/guide/component

我希望所有这些都可以帮助那些人: - )

答案 1 :(得分:0)

实际上,您不需要传递父表单即可。在 awesome-component 的模板中,添加一个 ng-form 标记,并使用它:

您的组件的模板:

<ng-form name="myComponentForm">
    <input type="number" ng-model="$ctrl.myModel" name="myField"/>
    <span ng-show="myComponentForm.myField.$invalid">There's an error</span>
</ng-form>

这是ngForm伪指令的含义,即在伪指令和组件中具有子表单,以对表单字段的子组进行验证。