简体   繁体   中英

Binding two components properties angular 5

I'm driving myself crazy trying to understand what's wrong inside my code. In the template of my 'search-item-main.component" I have two components: 'search-results.component' and 'item-generals.component'.

I've got an input whose text is binded to the input property 'searchText' inside search-result: when i write something inside the input, a function inside search-result calls a searching service and this part works just fine.

Inside search-result.component there is also the 'selectedItem'(with its event emitter) property which is modified by a button declared inside of search-result template.

Then I've got the second component 'item-generals', the ones I've problem with: I've tried to bind the input property 'item' like above to the selectedItem property defined inside search-result, but the ngOnChange event inside it is not raised.

I've searched all the day online and what's reported below should work, but it doesn't. I'm using typescript 2.6.2 with angular 5.2.0.

Thanks for the help!

search-item-main.component.html

 <div class="container-fluid" style="padding-top:70px;"> <div class="row"> <div class="col-sm-4 mb-3"> <div class="card"> <div class="card-body"> <h4>search:</h4> <form> <div class="form-group"> <input type="text" class="form-control" placeholder="placeholder" [(ngModel)]="inputText" [ngModelOptions]="{standalone: true}"> </div> </form> <search-results [searchText]="inputText" [(ngModel)]="selectedItem" ngDefaultControl></search-results> </div> </div> </div> <div class="col-sm-8"> <item-generals [item]="selectedItem"></item-generals> </div> </div> </div> 

search-results.component.ts

 import { Component, SimpleChanges, OnChanges, Input, Inject, Output, EventEmitter } from '@angular/core'; import { LightSearchResultModel } from './../../../models/search-item.models'; import { SearchItemService } from './../../../services/search-item.service'; @Component({ selector: 'search-results', templateUrl: './search-results.component.html', }) export class SearchResultsComponent implements OnChanges { @Input() searchText: string; @Output() selectedItemChange: EventEmitter<any> = new EventEmitter<any>(); public searchResults: Array<LightSearchResultModel>; private itemService: SearchItemService; public selectedItem: LightSearchResultModel; constructor(itemService: SearchItemService) { this.itemService = itemService; } async ngOnChanges(changes: SimpleChanges): Promise<void> { if (this.searchText.length > 3) { this.searchResults = await this.itemService.getMatchingItems(this.searchText); } } //Called with success by a button in the template public selectItem(item: LightSearchResultModel) { this.selectedItem = item; this.selectedItemChange.emit(this.selectedItem); } } 

item-generals.component.ts

 import { Component, SimpleChanges, OnChanges, Input, Inject } from '@angular/core'; import { GeneralInfoModel, LightSearchResultModel } from './../../../models/search-item.models'; import { SearchItemService } from '../../../services/search-item.service'; @Component({ selector: 'item-generals', templateUrl: './item-generals.component.html', }) export class ItemGeneralsComponent implements OnChanges { @Input() item: LightSearchResultModel; public generalItemInfo: GeneralInfoModel; private itemService: SearchItemService; constructor(itemService: SearchItemService) { this.itemService = itemService; } //this ngOnChanges is not raise async ngOnChanges(changes: SimpleChanges): Promise<void> { if (this.item) { this.generalItemInfo = await this.itemService.getGeneralItemInfo(this.item.itemCode); } } } 

Since ngOnChanges() is not invoked, this means that there is no binding change event. Objects are mutable, and most likely the reference to your LightSearchResultModel is not changing. Try to clone this object before emitting event. This will change the reference to the object, and the binding change will kick in.

public selectItem(item: LightSearchResultModel) {
    this.selectedItem = {...item}; // cloning with the spread operator
    this.selectedItemChange.emit(this.selectedItem);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM