Angular:为组件字段提供对服务功能的引用并从模板调用它无法按预期工作

Posted

技术标签:

【中文标题】Angular:为组件字段提供对服务功能的引用并从模板调用它无法按预期工作【英文标题】:Angular: Giving a component field a reference to a service function and calling it from template not working as expected 【发布时间】:2018-03-21 07:11:06 【问题描述】:

In my Plunker here(从官方文档修改Tour of Heroes应用)我在hero.service中创建了这个方法

  doHeroesExist(): boolean 
   console.log("doHeroesExist called..", this.heroesExist);
   alert("doHeroesExist called.." + JSON.stringify(this.heroesExist));
    return this.heroesExist;
  

并在app.component 类中使用它

  ngOnInit(): void 
    //this.getHeroes();
    this.heroesExist = this.heroService.doHeroesExist;
    console.log("app ngOnInit called...", this.heroesExist);

在模板中调用heroesExist()方法

<button (click)="heroesExist()">Do Heroes Exist?</button>

我对它的行为感到困惑。

当我点击 Do Heroes Exist? 按钮时,我希望控制台(和警报弹出窗口)会记录 “doHeroesExist called.. true”,但它会记录服务功能的整个主体:

doHeroesExist 调用.. ƒ () console.log("doHeroesExist 调用..", this.heroesExist); alert("doHeroesExist 被调用.." + JSON.stringify(this.heroesExist)); 返回 this.heroesExist;

为什么会这样?

为什么服务没有正确评估服务构造函数中定义的heroesExist = true;

插件链接:https://plnkr.co/edit/MBEGkqnV5kie9PB3az9K?p=preview

【问题讨论】:

您将this.heroService.doHeroesExist 视为一个属性,而不是像函数this.heroService.doHeroesExist() 一样调用它。最后缺少括号。那是你真正需要的吗? 【参考方案1】:

当你传递函数并稍后在另一个上下文中调用它时,函数中this 的上下文会丢失。这就是为什么您会看到警报显示“doHeroesExist called.. undefined”,因为您的服务方法中的this 并不是指服务本身。

要解决它,在将函数作为变量返回之前,将上下文绑定到它:

this.heroesExist = this.heroService.doHeroesExist.bind(this.heroService);

【讨论】:

哦,我以为 Typescript 解决了这些问题。谢谢你的解释! 好吧,IMO 这不是要解决的问题。 Typescript 引入了另一种解决方法,即粗箭头函数。如果你使用这个this.heroesExist = () =&gt; this.heroService.doHeroesExist();,你会得到同样的结果【参考方案2】:

在你的 plunker 中,只需替换 &lt;button (click)="heroesExist()"&gt;Do Heroes Exist?&lt;/button&gt;

 <button (click)="heroService.doHeroesExist()">Do Heroes Exist?</button>

这对我有用

【讨论】:

这很酷。我没有想到。我一直在组件中创建传递函数 看来我必须将heroService 设为app.component 的公共字段

以上是关于Angular:为组件字段提供对服务功能的引用并从模板调用它无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 中为动态加载的组件提供 @input

Angular开发者指南服务

Angular @Input 数组 - 如何引用不同的数组对象字段名称?

如何在 Angular 7 的激活链接中获取 url 参数并从服务类调用 rest api

使用 Jasmine 间谍进行 Angular 2 组件测试“没有 Http 提供者!”错误

Angular2:通过引用传递组件之间的交互