2017-03-07 92 views
3

我想創建包含其他自定義控件的自定義控件,並使用ngModel連接所有這些自定義控件。 像:將ngModel中的對象傳遞給自定義控件Angular2

PersonSearchComponent:

  • DeveloperSearchControl
    • 名稱 - 一些字符串輸入
    • ProffesionSelect - 自定義控件期待ProffesionModel
  • BuildingSearchControl
    • 這裏有些自定義控件
  • CountryCustomControl - 自定義控件期待CountryModel

  • PersonListComponent: 有關的一些服務從PersonSearchComponent項目-imported數據

  • SomeOtherSearchComponent
    • DeveloperSearchControl - 可重複使用的

所以現在我已經工作版本,但我想我已經取得了壞事(也許我應該用FormBuilder):

PersonSearch模板:

<div> 
      <developer-search-control [(ngModel)]="searchModel.developerSearchModel"></developer-search-control> 
      <building-search-control [(ngModel)]="searchModel.buildingSearchModel"></building-search-control> 
      <country-select [(ngModel)]="searchModel.countryModel"><country-select> 
    </div> 

ParentSearch部件

... 
export class PersonSearch { 
    @Output() searchDataEmitter= new EventEmitter();//Exports data to above component which contains this, and listComponent 
searchModel : PersonSearchModel : new PersonSearchModel(); 

    performSearch() 
    { 
     //gets data from service with searchModel and searchDataEmitter transpors it to above component 
    } 
} 

型號: PersonSearchModel:

developerSearchModel : DeveloperSearchModel = new DeveloperSearchModel(); 
buildingSearchModel: BuildingSearchModel = new BuildingSearchModel(); 
countryModel : CountryModel; 

DeveloperSearchModel:

name : string 
surname : string 
proffesion : ProfessionModel 

模板 developerSearchControl.component.html:

<div *ngIf="value">//This is the problem 
    <input [(ngModel)]="value.name"></input> 
    <input [(ngModel)]="value.surname"></input> 
    <profesion-select [(ngModel)]="value.ProffesionSelect"> 
</div> 

developerSearchControl.component:

... 
@Component({ 
    selector: 'developer-search-control', 
    templateUrl: './developerSearchControl.component.html', 
    providers: [{ 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => DeveloperSearchControlComponent), 
    multi: true, 
    }], 
}) 

export class DeveloperSearchControlComponent extends ElementBase<DeveloperSearchModel > { 
    protected model: NgModel; 

    constructor(
    @Optional() @Inject(NG_VALIDATORS) validators: Array<any>, 
    @Optional() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<any>, 
) { 
    super(validators, asyncValidators); 
    } 
} 

profesionSelect。組件

... 
@Component({ 
    selector: 'profesion-select', 
    template: ` 
    <div> 
     <label *ngIf="label">{{label}}</label> 
     <dx-select-box 
      [dataSource]="data" 
      [(ngModel)]="value" 
      displayExpr="proffesionName" 
      [placeholder]="placeholder" 
      [searchEnabled]="true" 
      > 
     </dx-select-box> 
    </div>`, 
     providers: [{ 
     provide: NG_VALUE_ACCESSOR, 
     useExisting: ProfessionComponent, 
     multi: true, 
    }], 
}) 

export class ProfessionComponent extends ElementBase<string> implements OnInit { 
    private data: ProfessionModel[]; 
    private label: string = 'proffesion :'; 
    private placeholder: string = 'Select profession'; 
    @ViewChild(NgModel) model: NgModel; 

    constructor(private proffesionService: ProfessionDataService, 
     @Optional() @Inject(NG_VALIDATORS) validators: Array<any>, 
     @Optional() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<any>, 
    ) { 
     super(validators, asyncValidators); 
    } 

    ngOnInit() { 
     this.professionService.getDevelopersProfessions().subscribe(
      data => { 
       this.data = data; 
      } 
     ); 
    } 
} 

ElementBase是與驗證通用ControlValueAccessor:http://blog.rangle.io/angular-2-ngmodel-and-custom-form-components/

所以我的問題是,當我爲孩子創造(developerSearch,buildingSearch)模板與ngModel傳遞的值不爲他們初始化我得到:

EXCEPTION: Uncaught (in promise): Error: Error in ./DeveloperSearchControlComponent class DeveloperSearchControlComponent - inline template:2:33 caused by: Cannot read property 'name' of null 
Error: Error in ./DeveloperSearchControlComponent class DeveloperSearchControlComponent - inline template:2:33 caused by: Cannot read property 'name' of null 

因爲ngModel的值在開始時爲null。所以我必須在看起來不好的子組件模板中使用* ngFor =「value」。 在模板驗證之前是否有任何解決方案來初始化對象?或者我這樣做是非常錯誤的?

+0

你嘗試了貓王運營商無處不在,你使用的價值?就像''。至少,這將抑制異常。 – mickdev

+1

@mickdev安全導航操作符不能用於'[(ngModel)]';) – Alex

+0

@ AJT_82我從來沒有嘗試過,但在我看來這是可能的。我不明白爲什麼不... – mickdev

回答

4

有使用雙向與安全導航操作結合的方式:

<input [ngModel]="value?.name" (ngModelChange)="value?.name ? value.name = $event : null"> 

道具:https://stackoverflow.com/a/36016472/5706293

+1

這就是答案,我還需要做一些初始化模型的工作。 – Mopa