与双向绑定和验证一个组件内自定义angular2形式输入组件 [英] Custom angular2 form input component with two way binding and validation inside a component

查看:674
本文介绍了与双向绑定和验证一个组件内自定义angular2形式输入组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法,使一个双向绑定输入组件,也可以在组件内部一个验证?

Is there a way to make a two way binding input component, that can also have a validation inside the component?

我试图做到的,是让我能在我的形式排成一个组成部分如下:

What I'm trying to achieve is to have a components that I could line up in my forms as follows:

<form #f="ngForm">
            <my-form-input [(inputModel)]="name" [inputField]="myFormInputName"></my-form-input>
            <my-form-input [(inputModel)]="name2" [inputField]="myFormInputName2"></my-form-input>
...
            <my-form-input [(inputModel)]="lastItem" [inputField]="lastItemName"></my-form-input>

</form>

我有以下设置并不能弄清楚,如何作出正确的:

I have a following setup and can't figure out, how to make it right:

组件:

import {Component,Input, Output,EventEmitter} from 'angular2/core'
import {FORM_DIRECTIVES}    from 'angular2/common';

@Component({
  selector: 'my-form-input',
  directives: [FORM_DIRECTIVES],
  template:
    `
    <input type="text" class="form-control"  id="i1" required [ngModel]="inputModel" (ngModelChange)="onChangeInput($event)" ngControl="ctrl" #ctrl="ngForm"/>
    <p>{{"Is field valid? I would like to make some decisions here depending on that: "+ctrl.valid}}</p>

  `
})
export class InputComponent {

  constructor(){};

  @Input()  inputField:string;
  @Input()  inputModel: Object;
  @Output() inputModelChange = new EventEmitter();

  onChangeInput(event){
    this.inputModel=event;
    this.inputModelChange.emit(event);
  }
}

该应用程序:

//our root app component
import {Component} from 'angular2/core'
import {FORM_DIRECTIVES}    from 'angular2/common';
import {InputComponent} from './my.input'


@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <p>Is there a way to make a custom 2 way binding form input component having also validation?</p>
      <form #f="ngForm">

        <my-form-input [(inputModel)]="name" [inputField]="myFormInputName"></my-form-input>

        <p>{{name}}</p>
      </form>
    </div>
  `,
  directives: [InputComponent,FORM_DIRECTIVES]
})
export class App {
  constructor() {
    this.name = 'Angular2'
  }
}

我也做了Plunker到ilustrate我的问题: http://plnkr.co /编辑/ 0vXjHbQmv7v7EKQcLWaa?p = preVIEW

推荐答案

您可以通过表单控件到你的组件来创建用于输入一个专用的控制。在此基础上新控件来显示错误时,他们的有效属性是

You can pass the form control to your component to create a dedicated control for the input. Based on this new control to display errors when their valid attributes are false:

@Component({
  selector: 'my-form-input',
  directives: [FORM_DIRECTIVES],
  template: `
    <input type="text" class="form-control"  id="i1"   
       [ngModel]="inputModel"
       (ngModelChange)="onChangeInput($event)"
       [ngFormControl]="formCtrl.controls[inputField]"/>
    <p>Is field valid? I would like to make some decisions
       here depending on that: {{formCtrl.controls[inputField].valid}}
    </p>
  `
})
export class InputComponent implements OnInit {
  @Input()  inputField:string;
  @Input()  formCtrl;
  @Input()  inputModel: Object;
  @Output() inputModelChange = new EventEmitter(); 

  ngOnInit() {
    this.formCtrl.control.addControl(
        this.inputField, new Control('', Validators.required));
  }

  onChangeInput(event){
    this.inputModel=event;
    this.inputModelChange.emit(event);
  }
}

您需要使用的AddControl 方法,使您的整个窗体与您在输入组件中创建的控件一致的状态。

You need to use the addControl method to make the state of your whole form consistent with controls you created within your input components.

在你的情况,你定义内联使用 ngControl 指令的控制。我做了一些测试,但我不能让它以这种方式工作......

In your case, you define your controls inline using the ngControl directive. I made some tests but I can't make it work this way...

下面是使用该组件从父一个方式:

Here is the way to use this component from the parent one:

@Component({
  selector: 'my-app', 
  template: `
    <form #f="ngForm">
      <my-form-input [(inputModel)]="name" [inputField]="myFormInputName" [formCtrl]="f"></my-form-input>
    </form>
  `,
  directives: [ FORM_DIRECTIVES, InputComponent ]
})
export class AppComponent {
}

这只是开始后,仍然是一个检查问题。形式的全局状态未更新,出现下列错误:

It remained a check problem just after starting. The global state of the form wasn't updated and the following error occured:

Expression '
    Valid : {{f.valid}} in AppComponent@1:24' has changed after it was checked. Previous value: '
    Valid : true'. Current value: '
    Valid : false'

要解决这个问题方面,看看根据 ChangeDetectorRef 类和 detectChanges 法朱利安的答案...

To fix this aspect, have a look at the Julien's answer based on the ChangeDetectorRef class and its detectChanges method...

下面是一个示例plunkr: https://plnkr.co/edit/Z4uOUq2q4iXdpo0J6R1o p = preVIEW

Here is a sample plunkr: https://plnkr.co/edit/Z4uOUq2q4iXdpo0J6R1o?p=preview.

希望它可以帮助你,
蒂埃里

Hope it helps you, Thierry

这篇关于与双向绑定和验证一个组件内自定义angular2形式输入组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆