angular 4个自己的表单元素组件
angular 4 own form element component
我是 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>
如果您不想 select 有自己的外观,这已经足够了。我的目标是为此创建一个组件,我可以在其中创建 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/
这是我在表单中执行此操作的方法(请记住,我使用的是带有表单生成器的反应式表单,而不是带有 ngModel 的模板驱动表单):
首先,我在名为forms
.
的目录中创建了一个自定义的FormModule
Next,里面有各种表单组件。让我们以 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`.
}
}
这种设计的好处可能不会立即非常明显,但它使我们能够做一些事情:
- 首先,只要导入自定义
FormModule
,我们就可以在应用中的任何地方重复使用 login-form
组件。如果我们改变它,它会自动更新到任何地方。保持干燥。
- 接下来,我们可能不希望每个地方都使用相同的提交 button/text,我们可能希望它在不同的位置做不同的事情,所以
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>
我是 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>
如果您不想 select 有自己的外观,这已经足够了。我的目标是为此创建一个组件,我可以在其中创建 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/
这是我在表单中执行此操作的方法(请记住,我使用的是带有表单生成器的反应式表单,而不是带有 ngModel 的模板驱动表单):
首先,我在名为forms
.
Next,里面有各种表单组件。让我们以 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`.
}
}
这种设计的好处可能不会立即非常明显,但它使我们能够做一些事情:
- 首先,只要导入自定义
FormModule
,我们就可以在应用中的任何地方重复使用login-form
组件。如果我们改变它,它会自动更新到任何地方。保持干燥。 - 接下来,我们可能不希望每个地方都使用相同的提交 button/text,我们可能希望它在不同的位置做不同的事情,所以
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>