实际的复杂代码被抽象以使其更具可读性。
在我们的Angular 2中项目中,我们有一个组件 <top-component>
(1 级)如下所示:
<top-component>
</top-component>
其中有以下模板:<some-form>
(2 级):
<some-form>
</some-form>
其中包含以下模板(LEVEL 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
元素。
最佳答案
我通过使用共享服务解决了这个问题。
长话短说:
- 为表单元素创建一个组件(在本例中为选择)。 (你已经有了这个)
- 在表单组件和表单字段组件之间创建共享服务。
- 在表单字段组件内,在模型更改时,您可以将新模型发送到服务。
- 在表单组件中,您可以订阅表单字段模型上的任何更改,并更新所有模型。
- 提交后,您将拥有一个包含表单字段组件模型的对象,您可以通过每个表单字段组件调用的共享服务来更新该模型。
有了这个,你就可以让它发挥作用。而且您可以拥有非常动态的表单。
如果您需要示例,请告诉我,当我可以时,我会在这里为您提供一个简单的示例。
希望对您有帮助!干杯!
更新:
让我们从 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...
}
);
个人想法:
- 我喜欢这种方法,因为您可以在本地管理表单的每个元素。当您有多选外部库、日期选择器等时,它会变得很方便......
- 我发送/接收对象而不仅仅是模型,因为通过对象我可以动态地决定元素的行为。想象一下,您从表单组件中的数据库获取数据,循环它并调用 SharedService 方法来更新字段...它们将像您告诉它们的那样显示:突出显示、选择、禁用等...
- 最终,如果您动态渲染表单的每个元素...您将拥有一个具有 100% 动态和抽象潜力的表单。我设法做到了,现在我只有一个向量,它说明了表单的哪些元素必须渲染以及如何渲染。
关于javascript - 如何在LEVEL 3的表单提交中获取LEVEL 4's select element'的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44203345/