绑定两个组件属性angular 5

时间:2018-03-06 14:25:51

标签: html angular typescript data-binding

我正在疯狂地试图理解我的代码中的错误。 在我的'search-item-main.component'的模板中,我有两个组件:'search-results.component'和'item-generals.component'。

我有一个输入,其文本绑定到搜索结果中的输入属性'searchText':当我在输入中写入内容时,搜索结果中的函数调用搜索服务,这部分工作正常。

在search-result.component中,还有'selectedItem'(及其事件发射器)属性,该属性由在搜索结果模板内声明的按钮修改。

然后我有第二个组件'item-generals',我遇到的问题:我试图将上面的输入属性'item'绑定到search-result中定义的selectedItem属性,但是其中的ngOnChange事件不会被引发。

我在网上搜索了一整天,下面报道的内容应该有效,但事实并非如此。 我正在使用带有角度5.2.0的typescript 2.6.2。

感谢您的帮助!

搜索项-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>

搜索-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);
  }
}

项-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);
    }
  }
}

1 个答案:

答案 0 :(得分:0)

由于未调用ngOnChanges(),这意味着没有绑定更改事件。对象是可变的,并且很可能对LightSearchResultModel的引用没有改变。尝试在发出事件之前克隆此对象。这将改变对象的引用,并且绑定更改将启动。

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