如何在 LEVEL 3 的表单提交中获取 LEVEL 4 的 select 元素的值?
How to get LEVEL 4's select element's values in LEVEL 3's form submit?
实际的复杂代码被抽象出来以使其更具可读性。
在我们的 Angular 2 项目中,我们有一个组件 <top-component>
(LEVEL 1),如下所示:
<top-component>
</top-component>
其中有以下模板:<some-form>
(LEVEL 2):
<some-form>
</some-form>
具有以下模板(级别 3):
<form #f="ngForm" (submit)="handleFormSubmit(f)" >
<input name="Label" value="Label" />
<input name="Value" value="Value" />
<some-select></some-select>
<button> Cancel </button>
<button> Save </button>
</form>
<some-select>
(4 级)的模板是:
<select name="selectData" ngDefaultControl [(ngModel)]="selectData">
<option *ngFor="let option of options" [ngValue]="option.value">{{option.label}}</option>
</select>
问题是当我们提交 #f="ngForm"
到 handleFormSubmit(f)
时,
f.value
值没有来自 some-select
的 select
元素的值。
我使用共享服务解决了这个问题。
长话短说:
- 为您的表单元素创建一个组件(select,在本例中)。 (你已经有了)
- 在表单组件和表单字段组件之间创建共享服务。
- 在您的表单域组件内,在模型更改时,您将新模型发送到服务。
- 在您的表单组件中,您订阅表单字段模型的任何更改并更新所有模型。
- 提交时,您将拥有一个 object,其中包含您更新的每个表单域组件的模型,这要归功于每个表单域组件调用的共享服务。
有了这个,你就可以让它工作了。而且你可以有一个非常动态的形式。
如果你需要一个例子告诉我,我什么时候可以在这里给你一个简单的例子。
希望对您有所帮助!干杯!
更新:
让我们从 child 转到 parent。
SelectField
分量:
@Component({
selector: 'select-field',
template: `
<select class="col-md-12 form-control input-xs" name="ibos-newsletter" [(ngModel)]="fieldset.value" (ngModelChange)="onChange($event)">
<option *ngFor="let option of options" [ngValue]="option.id"
[selected]="option.id === condition">{{option.name}}
</option>
</select>
`
})
export class SelectField implements OnInit {
private fieldset = {};
private options = <any>[];
private fieldName = 'SelectField';
constructor(private sharedService: SharedService) {
// we get data from our shared service. Maybe the initial data is gathered and set up in the Form service.
// So if the Form service just calls this method we are subscribed and we get the data here
this.sharedService.updateFieldsetsListener$.subscribe((fieldset) => {
if (fieldset.field=== this.fieldName) {
this.selectModel = fieldset;
}
}
);
}
ngOnInit() {
}
onChange() {
// fieldset.value (our model) is automatically updated, because this is binded with (ngModelChange). This means that we are sending an updated fieldset object
this.sharedService.updateFieldsets(this.fieldset);
}
}
SharedService
服务:
@Injectable()
export class SharedService {
updateFieldsetsListener$: Observable<any>;
private updateFieldsetsSubject = new Subject<any>();
constructor(private jsonApiService: JsonApiService) {
this.updateFieldsetsListener$ = this.updateFieldsetsSubject .asObservable();
}
updateFieldsets(fieldset) {
this.updateFieldsetsSubject .next(fieldset);
}
}
表单组件:
在你的构造函数中你应该有订阅:
this.sharedService.updateFieldsetsListener$.subscribe((fieldset) => {
// Here you have a full object of your field set. In this case the select.
// You can add it to a form object that contains all the fieldsets objects...
// You can use these formfields objects (instead of sending / receiving only the model) to dynamically: select an option, disable an input, etc...
}
);
个人想法:
- 我喜欢这种方法,因为您可以在本地 管理表单的每个元素。当您拥有多个select 外部库、日期选择器等时变得很方便...
- 我发送/接收 objects 而不仅仅是模型,因为通过 objects 我可以更改以动态决定元素的行为。想象一下,您从 Form 组件中的 DB 获取数据,循环它并调用 SharedService 方法来更新字段......它们将按照您告诉他们的方式显示:突出显示,selected,禁用等。 .
- 最终,如果您动态呈现表单的每个元素...您将拥有一个有可能成为 100% 动态和抽象的表单。我设法做到了,现在我只有一个向量,说明必须渲染表单的哪些元素以及如何渲染。
实际的复杂代码被抽象出来以使其更具可读性。
在我们的 Angular 2 项目中,我们有一个组件 <top-component>
(LEVEL 1),如下所示:
<top-component>
</top-component>
其中有以下模板:<some-form>
(LEVEL 2):
<some-form>
</some-form>
具有以下模板(级别 3):
<form #f="ngForm" (submit)="handleFormSubmit(f)" >
<input name="Label" value="Label" />
<input name="Value" value="Value" />
<some-select></some-select>
<button> Cancel </button>
<button> Save </button>
</form>
<some-select>
(4 级)的模板是:
<select name="selectData" ngDefaultControl [(ngModel)]="selectData">
<option *ngFor="let option of options" [ngValue]="option.value">{{option.label}}</option>
</select>
问题是当我们提交 #f="ngForm"
到 handleFormSubmit(f)
时,
f.value
值没有来自 some-select
的 select
元素的值。
我使用共享服务解决了这个问题。
长话短说:
- 为您的表单元素创建一个组件(select,在本例中)。 (你已经有了)
- 在表单组件和表单字段组件之间创建共享服务。
- 在您的表单域组件内,在模型更改时,您将新模型发送到服务。
- 在您的表单组件中,您订阅表单字段模型的任何更改并更新所有模型。
- 提交时,您将拥有一个 object,其中包含您更新的每个表单域组件的模型,这要归功于每个表单域组件调用的共享服务。
有了这个,你就可以让它工作了。而且你可以有一个非常动态的形式。
如果你需要一个例子告诉我,我什么时候可以在这里给你一个简单的例子。
希望对您有所帮助!干杯!
更新:
让我们从 child 转到 parent。
SelectField
分量:
@Component({
selector: 'select-field',
template: `
<select class="col-md-12 form-control input-xs" name="ibos-newsletter" [(ngModel)]="fieldset.value" (ngModelChange)="onChange($event)">
<option *ngFor="let option of options" [ngValue]="option.id"
[selected]="option.id === condition">{{option.name}}
</option>
</select>
`
})
export class SelectField implements OnInit {
private fieldset = {};
private options = <any>[];
private fieldName = 'SelectField';
constructor(private sharedService: SharedService) {
// we get data from our shared service. Maybe the initial data is gathered and set up in the Form service.
// So if the Form service just calls this method we are subscribed and we get the data here
this.sharedService.updateFieldsetsListener$.subscribe((fieldset) => {
if (fieldset.field=== this.fieldName) {
this.selectModel = fieldset;
}
}
);
}
ngOnInit() {
}
onChange() {
// fieldset.value (our model) is automatically updated, because this is binded with (ngModelChange). This means that we are sending an updated fieldset object
this.sharedService.updateFieldsets(this.fieldset);
}
}
SharedService
服务:
@Injectable()
export class SharedService {
updateFieldsetsListener$: Observable<any>;
private updateFieldsetsSubject = new Subject<any>();
constructor(private jsonApiService: JsonApiService) {
this.updateFieldsetsListener$ = this.updateFieldsetsSubject .asObservable();
}
updateFieldsets(fieldset) {
this.updateFieldsetsSubject .next(fieldset);
}
}
表单组件:
在你的构造函数中你应该有订阅:
this.sharedService.updateFieldsetsListener$.subscribe((fieldset) => {
// Here you have a full object of your field set. In this case the select.
// You can add it to a form object that contains all the fieldsets objects...
// You can use these formfields objects (instead of sending / receiving only the model) to dynamically: select an option, disable an input, etc...
}
);
个人想法:
- 我喜欢这种方法,因为您可以在本地 管理表单的每个元素。当您拥有多个select 外部库、日期选择器等时变得很方便...
- 我发送/接收 objects 而不仅仅是模型,因为通过 objects 我可以更改以动态决定元素的行为。想象一下,您从 Form 组件中的 DB 获取数据,循环它并调用 SharedService 方法来更新字段......它们将按照您告诉他们的方式显示:突出显示,selected,禁用等。 .
- 最终,如果您动态呈现表单的每个元素...您将拥有一个有可能成为 100% 动态和抽象的表单。我设法做到了,现在我只有一个向量,说明必须渲染表单的哪些元素以及如何渲染。