2017-03-07 11 views
3

他のカスタムコントロールを含むカスタムコントロールを作成し、それらのすべてを接続するngModelを使用したいと考えています。 ように:ngModelのオブジェクトをカスタムコントロールに渡すAngular2

PersonSearchComponent:

  • DeveloperSearchControl
    • 名 - いくつかの文字列を入力
    • ProffesionSelect - ProffesionModel
  • BuildingSearchControlを期待してカスタムコントロール
    • いくつかのカスタムコントロールここ
  • CountryCustomControl - 期待してカスタムコントロールをCountryModel

  • PersonListComponent:いくつかのサービスによってPersonSearchComponentから項目に関する -importedデータ

  • SomeOtherSearchComponent
    • DeveloperSearchControl - 再利用可能な
今私が働いているバージョンについては、これ

が、私は、私は悪い何かをしたと思います(多分私はFormBuilderを使用する必要があります):

人物検索テンプレート:

<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 = "値"を悪い見える子コンポーネントのテンプレートで使用する必要があります。 テンプレート検証前にオブジェクトを初期化するソリューションはありますか?またはこれを非常に間違っているイム?

+0

あなたが値を使用してどこにでもエルビス演算子を試してみたのですか? ''のようなものです。少なくとも、それは例外を抑制します。安全なナビゲーション演算子は '[(ngModel)]で使用することはできません – mickdev

+1

@mickdev';) – 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

関連する問題