2017-03-07 117 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

相关问题