如何在 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-selectselect 元素的值。

我使用共享服务解决了这个问题。

长话短说:

  • 为您的表单元素创建一个组件(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% 动态和抽象的表单。我设法做到了,现在我只有一个向量,说明必须渲染表单的哪些元素以及如何渲染。