2017-05-26 43 views
1

抽象出實際的複雜代碼以使其更具可讀性。如何在LEVEL 3的表單提交中獲得LEVEL 4的select元素值?

在我們Angular 2的項目,我們有這樣的組件<top-component>LEVEL 1):

<top-component> 
</top-component> 

它具有以下的模板:<some-form>LEVEL 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>LEVEL 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元素。

回答

1

我通過使用共享服務解決了這個問題。

長話短說:

  • 爲表單元素創建一個組件(選擇,在這種情況下)。 (你已經有了這個)
  • 在表單的組件和表單域組件之間創建一個共享服務。
  • 在您的formfield組件中,在模型更改時,您將新模型發送到服務。
  • 在您的表單組件中,您訂閱了表單字段模型上的任何更改,並更新了所有模型。
  • 提交時,您將擁有一個對象,其中包含您更新的表單域組件的模型,這要感謝每個表單域組件調用的共享服務。

用這個,你可以使它工作。你可以有一個非常有活力的形式。

如果你需要一個例子告訴我,當我可以的時候,我會在這裏給你一個簡單的例子。

希望它有幫助!乾杯!

更新:

讓我們從孩子到父母這裏。

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); 
    } 
} 

表單組件:

內部構造函數,你應該有潛艇cribe:

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%動態和抽象的表單。我設法做到了,現在我只有一個向量,表示必須呈現哪些表單元素以及如何呈現。
+0

讓我們完成這個答案與一些[Hello World示例](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) – xameeramir

+2

@xameeramir好吧,給我幾分鐘,youl'll有一個例子。 – SrAxi

+0

@xameeramir我已經更新了我的答案。如果有什麼不清楚的地方,或者如果你想讓我改變一些東西讓我知道。事情是,現在你的手變髒了*你可以發送/接收一個包含你的字段集的屬性的對象,例如:fieldset = {value:'car',selected:true,highlight:false,toogleable: false,disabled:true}' – SrAxi