角度5-通过@Input

时间:2018-08-21 15:11:25

标签: angular angular5

我正在尝试使用angular创建自动完成指令。

我为这个问题做了一个小演示:

import { Component, NgModule, VERSION, Directive, Injectable, Input } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@Directive({
  selector: "[autocompleter]",
  host: {
    "(keyup)": "onKey($event)"
  }
})
export class AutocompleterDirective{
  @Input("autocompleter") getFilteredData: (term: string) => Promise<string[]>;
  
  private term = "";
  
  public onKey(event: any) {
    this.term = event.target.value;
    this.search();
  }
  private search() {
    this.getFilteredData(this.term)
      .then((res) => {
        //do something to show the results list
      });
  }
}

@Injectable()
export class DataService {
  searchStrings: string[];
  getStringsFilteredByTerm(term: string) {
    //do some filters on searchStrings...
    return this.searchStrings;
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <input type="text" [autocompleter]="getFilteredData" autocomplete="off" />
    </div>
  `,
})
export class AppComponent{
  constructor(private dataService: DataService) {
  }
  private getFilteredData(term: string){
    let filteredStrings = this.dataService.getStringsFilteredByTerm(term); //"this" refers to the AutocompleterDirective instead of AppComponent
    var promise = new Promise((resolve, reject) => {
      resolve(filteredStrings);
    });
    return promise;
  }
}

@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent, AutocompleterDirective],
  providers: [DataService],
  bootstrap: [AppComponent]
})
export class AppModule {}

问题在于,在“ AppComponent”的“ getFilteredData”函数中,“ this”是指“ AutocompleterDirective”而不是“ AppComponent”, 我得到这个错误:

  

无法读取未定义的属性'getStringsFilteredByTerm'

我需要从注入到“ AppComponent”的“ dataService”中获取数据。

有什么办法解决这个问题?

2 个答案:

答案 0 :(得分:3)

您将失去作用域,可以使用箭头函数语法定义函数以保持正确的作用域,如下所示:

  getFilteredData = (term: string) => {
    let filteredStrings = this.dataService.getStringsFilteredByTerm(term); //"this" refers to the AutocompleterDirective instead of AppComponent
    var promise = new Promise((resolve, reject) => {
      resolve(filteredStrings);
    });
    return promise;
  }

旁注:请注意,我没有将其声明为私有,但是如果您实际上将该函数定义为私有,然后尝试在模板中传递它,尽管开发服务器可以正常工作,但是您的prod构建将失败。

答案 1 :(得分:1)

在您的组件中,对于要传递的功能,在其上添加.bind(this),看看是否可行:

const theFunc = () => {
    // blah
}.bind(this)

并通过它。

如果失败,请尝试相同的操作,但使用ES5函数语法。