我正在尝试使用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”中获取数据。
有什么办法解决这个问题?
答案 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函数语法。