2017-07-17 74 views
0

我想創建我的第一個Angular 2應用程序。像往常一樣,我立即遇到了我想創建的模型的麻煩。我有一個模型來創建artilces之間的父子關係。 例如:我想補充的文章,我的購物籃一些子對象如下:角度2/4反應形式與陣列

IArticle[] = [ 
{ 
    id: 1, 
    parentArticle: 1234596, 
    description: 'some description for parent' 
    children: [ 
     { 
      id: 1, 
      childArticle: 123457, 
      childDescription: 'some description for first child' 
     }, 
     { 
      id: 2, 
      childArticle: 123467, 
      childDescription: 'some description for second child' 
     }, 
     ..... 
    ] 

在打字稿我定義的接口爲我的文章。子對象有自己的界面,這個界面略有不同。

由於這些子對象是一個小的固定集,我想使用下拉列表添加這些子對象。我希望這些對象在點擊時顯示爲帶有刪除的按鈕(可選用帶有「你確定」的模式彈出的問題)。所以我認爲下拉列表旁邊的按鈕應該將下拉列表值添加到數組中。這工作正常時,我將值添加到正常的類型數組。但是現在我想用「Reactive Form」來包裝這個數組。

有人可以幫助我如何使用這些Reactive窗體中的數組以及如何將它們包裝在FormControl對象中。我看着FormArray的「控制」,但不知道這是我在尋找什麼。它接收一組FormControls,而不是一組數據。也許Reactive Forms不是正確的決定?希望有人能把我放在正確的軌道上。

我的HTML模板如下(從代碼剝離引導代碼)

<form autocomplete="off"> 
     <input type="text" Placeholder="Article Number" /> 
    <div > 
     <button *ngFor="let child of children"> 
     <span class="glyphicon glyphicon-remove-circle text-danger"></span> 
     {{ child.childArticle }} 
     </button> 
    </div> 
    <div > 
     <select class="form-control inline"> 
      <option value="">Select Service..</option> 
      <option *ngFor="let serviceOption of serviceOptions" [ngValue]="serviceOption.serviceNumber"> 
       {{serviceOption.serviceDescription}} 
      </option> 
     </select> 
      <button (click)="onAddService()"> 
      Add 
      </button> 
    </div> 
    <div> 
     <button type="submit"> 
     Save 
     </button> 
    </div> 
    </form> 

親切的問候。

------ 打字稿代碼:

export class NewServiceComponent implements OnInit { 
    newServiceForm: FormGroup; 
    serviceOptions: IServiceArticle[] = [ 
    { 'id': 1, 'serviceNumber': 123456, serviceDescription: 'description 1' }, 
    { 'id': 2, 'serviceNumber': 456789, serviceDescription: 'description 2' }, 
    { 'id': 3, 'serviceNumber': 123456, serviceDescription: 'description 3' }, 
]; 
selectedServiceOption: IServiceArticle; 
newArticle: IService; 

constructor(private _fb: FormBuilder) { 
} 

createForm() { 
this.newServiceForm = this._fb.group({ 
    services: this._fb.array([]), 
    articleNumber: this._fb.control(null, Validators.required), 
}) 
} 

ngOnInit() { 
    this.createForm(); 
} 

onAddService() { 
    const arrayControl = <FormArray>this.newServiceForm.controls['services']; 
    let newgroup = this._fb.group({ 
    serviceNumber: this.selectedServiceOption.serviceNumber, 
    serviceDescription: this.selectedServiceOption.serviceDescription, 
    }) 
    arrayControl.push(newgroup); 
} 
} 
+0

只是想知道'select',這可能意味着用戶可以一次又一次地選擇相同的值? – Alex

+0

在這個時候它可以。驗證邏輯應該被更新以避免這種情況。對於我對角度的理解,目前這不是問題。 –

+0

嘿,它的答案是怎麼回事?有幫助還是需要進一步的幫助? :) – Alex

回答

0

當創建一個反應形式,首先必須的主要形式組,你將有形式組內部的formArray控制。做完這些之後,您會將任何現有的孩子添加到該表單陣列中,並且每個孩子將成爲自己的表單組。

constructor(private fb: FormBuilder){ 
    myTypeScriptChildrenObjects = functionToGetTheChildrenArray(); 
} 
... 

createForm(){ 
    this.form = this.fb.group({ 
     childrenArray: this.fb.array([]) 
    }) 

    const arrayControl = <FormArray>this.orderForm.controls['childrenArray']; 
    this.myTypeScriptChildrenObjects.forEach(item => { 
     let newGroup = this.fb.group({ 
      prop1: [item.prop1], 
      prop2: [item.prop2], 
      prop3: [item.prop3] 
     }) 
     arrayControl.push(newGroup); 
    }) 
} 

當通過這些在你的HTML騎自行車,你做這樣的事情:

<select formArrayName="childrenArray"> 
      <option [formGroupName]="i" *ngFor="let line of form.controls['childrenArray'].controls; index as i" text="prop1" value="prop2"> 
+0

對不起,但以我的角度知識你的答案是不夠的。我得到了多個錯誤。嘗試了不同的事情,但不知道在哪裏看。我在窗體中添加了[formGroup] =「formnameintypescipt」指令。錯誤:FormGroupName必須與父窗體組指令一起使用。您需要添加一個formGroup 指令並將其傳遞給現有的FormGroup實例(您可以在您的類中創建一個實例)。 –

+0

這是正確的方法,在反應形式中,您應該專注於在邏輯端創建控件並使用結構指令將它們映射到模板 – LookForAngular

+0

是您的formnameintypescript組件中的變量嗎? – LookForAngular

0

嘗試下面的代碼,它似乎工作,因爲它應該....

對於形式,你需要添加[formGroup],所以:

<form [formGroup]="newServiceForm"> 

而且由於這是一個內部FO rmgroup現在,它不會接受[(ngModel)]select沒有窗體控制。我們可以使用[ngModelOptions]="{standalone: true}"

還我會再更改[ngValue]來指代對象繞過此:[ngValue]="serviceOption"

然後我們加入選擇的值,並將它推到形式排列,就像你做了。

在模板中,我們現在想迭代這個表單數組。總而言之,模板應該是這個樣子:

<form [formGroup]="newServiceForm"> 
    <div formArrayName="services"> 
    <button *ngFor="let child of newServiceForm.controls.services.controls; 
     let i = index" [formGroupName]="i"> 
     <span [innerHtml]="child.controls.serviceDescription.value"> </span> 
    </button> 
    </div> 

<select [(ngModel)]="selectedServiceOption" [ngModelOptions]="{standalone: true}"> 
    <option>Select Service..</option> 
    <option *ngFor="let serviceOption of serviceOptions" [ngValue]="serviceOption"> 
      {{serviceOption.serviceDescription}} 
    </option> 
</select> 
<button (click)="onAddService()"> Add </button> 
</form> 

表單控件也可以設置成變量,讓你可以避開那些長的路徑。

正如評論中所討論的那樣,這並沒有考慮到用戶可以一遍又一遍地選擇相同的值的事實,但這與問題無關。