我有一个非常奇怪的问题,我还没有找到原因。我尝试在Angular 2中显示一个文本框组件,您可以在单击按钮时为其提供消息,按钮标签和调用的回调。
这是我的组件:
@Component({
selector: 'text-box',
templateUrl: './textbox.component.html',
styleUrls: ['./textbox.component.styl']
})
export default class TextBoxComponent implements AfterViewInit {
content: String;
btnCaption: String;
callback: () => void;
constructor(@Inject(TextBoxService) private service: TextBoxService) {
}
ngAfterViewInit(): void {
this.service.init(this.show);
}
public show(message: String, btnCaption: String, callback: () => void) {
this.content = message;
this.btnCaption = btnCaption;
this.callback = callback;
// (1)
// set opacity 1
}
public btnOnClick() {
// (2)
this.callback();
this.dismiss();
}
public dismiss() {
// set opacity 0
}
}
组件是单例,无法注入,因此您不能简单地从外部调用组件上的show()
。因此,我添加了一个服务并将方法引用到其中(请参阅组件的ngAfterViewInit()
方法):
@Injectable()
export default class TextBoxService {
private showCallback: (m: String, b: String, c: () => void) => void;
public init(showCallback: (m: String, b: String, c: () => void) => void) {
this.showCallback = showCallback;
}
public show(message: String, btnCaption: String, callback: () => void) {
this.showCallback(message, btnCaption, callback);
}
}
它由另一个这样的服务调用:
this.textBoxService.show(
'Wollen Sie einen Kredit aufnehmen?',
'Ja', () => {
ziel.activate();
this.activatedEvents.set(event, ziel);
this.inputService.kreditInput.summe = ziel.getPrice() - ziel.getLiquidFunds();
this.inputService.kreditInput.startdatum = date;
});
但是,当调用上面的按钮时,文本不会更新,监听器也不会附加到按钮上(显示this.callback() is not a function
)。我调试了它(将console.log()
放在组件中的(1)和(2)上)并发现两个方法都被正确调用。在(1)成员content
,btnCaption
和callback
被正确设置 - 但在(2)上,这些成员是未定义的!
我尝试用function()
语法替换fat-arrow-syntax,但没有成功。我也尝试对show()
内的字符串进行硬编码,但是当通过buttonClick访问它时,它仍然是未定义的。
似乎在(1)和(2)上有两个不同的对象被访问。我不知道这种行为的原因是什么。有什么想法吗?
答案 0 :(得分:1)
应该按设计作为回调传递的类原型方法(如在this.service.init(this.show)
中)应定义为箭头类属性:
public show = (message: String, btnCaption: String, callback: () => void) => { ... };
或受到班级建设的约束:
constructor(@Inject(TextBoxService) private service: TextBoxService) {
this.show = this.show.bind(this);
}
或者,装饰器可用于更整洁的语法,例如, @autobind
from core-decorators