【问题标题】:angular 4 own form element componentangular 4自带表单元素组件
【发布时间】:2017-12-14 12:56:29
【问题描述】:

我是 Angular 的初学者,我可能需要一些帮助。首先,我将展示它是如何工作的,然后我将写下我希望它如何工作。

这是使用 ngModel 时的常规方式:

    <form>
      <input name="name" placeholder="name" [(ngModel)]="model.name" value="" />
      <select name="select" [(ngModel)]="model.select">
         <option value="1">..</option>
         ...
      </select>
      <input type="button" value=" click me" />
    </form>

如果您不希望选择有自己的外观,这已经足够了。我的目标是为此创建一个组件,我可以在其中创建 div 和其他我可以设计以适应此表单元素的未来显示的内容。另一方面,我想保持 ngModel 的舒适性。所以模板在我的目标中应该是这样的:

    <form>
      <input name="name" placeholder="name" [(ngModel)]="model.name" value="" />
      <app-select label="label" name="select" [placeholder]="'placeholder'" [(ngModel)]="select" [options]="options"></app-select >
      <input type="button" value=" click me" />
    </form>

我已经尝试过创建这样的东西,但我失败了,很遗憾:( 可以请比我有更多经验的人帮助我吗? 提前感谢您的时间和答案!

如有必要,我可以在这里重新创建一些最小的东西:https://stackblitz.com/

【问题讨论】:

标签: angular angular4-forms


【解决方案1】:

以下是我如何在表单中使用此表单(请记住,我在表单构建器中使用反应式表单,而不是使用 ngModel 的模板驱动表单):

首先,我在名为 forms 的目录中创建了一个自定义 FormModule。

接下来,里面有各种表单组件。我们以LoginFormComponent 为例。

这里是LoginFormComponent

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
    selector: 'login-form',
    templateUrl: './login-form.component.html'
})
export class LoginFormComponent implements OnInit {
    @Output() onChange: EventEmitter<FormGroup> = new EventEmitter();

    form: FormGroup;

    constructor(private fb: FormBuilder) {
        this.form = this.fb.group({
            email: [null, Validators.email],
            password: [null, [Validators.required, Validators.minLength(6), Validators.maxLength(60)]]
        });

        this.form.valueChanges.subscribe(() => this.onChange.emit(this.form));
    }

    ngOnInit() {
        this.onChange.emit(this.form);
    }
}

这是 HTML:

<form autocomplete="off" [formGroup]="form">
    <div class="form-group">
        <label for="username">Email *</label>
        <input type="text" id="username" class="form-control" placeholder="Enter your email address" formControlName="email" autofocus>
        <control-messages [control]="form.get('email')"></control-messages>
    </div>

    <label for="password">Password *</label>
    <input type="password" id="password" class="form-control" placeholder="Enter your password" formControlName="password">
    <control-messages [control]="form.get('password')" [label]="'Password'"></control-messages>
</form>

现在,在导入 FormModule 的模块中的任何自定义组件中,我可以执行以下操作:

app.component.html:

<login-form (onChange)="form = $event"></login-form>

<button (click)="submit()">Submit</button>

app.component.ts:

@Component({...})
export class AppComponent {
    form: FormGroup;

    submit() {
        // Do something with `this.form`.
    }
}

这种设计的好处可能不是马上就很明显,但它可以让我们做一些事情:

  1. 首先,只要我们导入自定义的FormModule,我们就可以在应用程序的任何地方重复使用login-form 组件。如果我们更改它,它将自动在任何地方更新。保持干燥。
  2. 接下来,我们可能不希望每个地方都相同的提交按钮/文本,我们可能希望它在不同的位置做不同的事情,所以login-form组件只包含表单本身,任何提交逻辑都在外部处理它的重用能力。当您有用于创建和编辑的表单时,这很重要。编辑按钮可以保存数据,而创建按钮可以创建新的东西。如果将提交按钮放在表单组件中,这种重用并不容易。

对于稍微复杂一点的表单,比如说可以接受一些默认值的表单,看看这个例子TagFormComponent

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { Tag } from 'shared';

@Component({
    selector: 'tag-form',
    templateUrl: './tag-form.component.html'
})
export class TagFormComponent implements OnInit {
    @Output() onChange: EventEmitter<FormGroup> = new EventEmitter();

    form: FormGroup;

    constructor(private fb: FormBuilder) {
        this.form = this.fb.group({
            name: [null, Validators.email]
        });

        this.form.valueChanges.subscribe(() => {
            this.onChange.emit(this.form);
        });
    }

    @Input()
    set tag(tag: Tag) {
        if (tag) {
            this.form.patchValue(tag);
        }
    }

    ngOnInit() {
        this.onChange.emit(this.form);
    }
}

这个遵循与LoginFormComponent 相同的一般思想,除了这个可以为表单传递一些默认值。像这样:

<tag-form [tag]="tag" (onChange)="form = $event"></tag-form>

【讨论】:

    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 2018-02-20
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 2018-04-22
    • 1970-01-01
    相关资源
    最近更新 更多