简体   繁体   English

Angular 2服务获取返回未定义

[英]Angular 2 service get returns undefined

In my current project, I have a very simple service which sets a string when a request comes from first page and show it in the second page using the same service. 在我当前的项目中,我有一个非常简单的服务,当请求来自第一页时设置一个字符串,并使用相同的服务在第二页中显示它。 Setting the text is working perfectly. 设置文本效果很好。 But when I called the get function, it returns undefined. 但是,当我调用get函数时,它返回未定义。

This is my service 这是我的服务

import { Injectable } from '@angular/core';

@Injectable()
export class TsService {

  constructor() { }

  ts: string;

  getTs() : string {
      return this.ts;
  }

  setTs(ts) : void {
      this.ts = ts;
  }

}

In my first component I imported the Service 在第一个组件中,我导入了服务

import { TsService } from './ts.service';

and added it to the providers 并将其添加到提供商

providers: [TsService]

and initialized in the contructor 并在构造器中初始化

private tsService: TsService

and to the button click, I set a string as well 并点击按钮,我也设置了一个字符串

this.tService.setTs(form.value.member)

In my second component, followed the same steps mentioned above except in the constructor I assigned as follows 在我的第二个组件中,遵循上面提到的相同步骤,但在我分配的构造函数中,如下所示

this.ts = tsService.getTs();

but it gives me undefined. 但这给了我不确定的东西。 Is there anything that I missed 有什么我想念的吗

Depending on the order in which stuff is executed it may well be that 根据执行任务的顺序,很可能是

this.tService.setTs(form.value.member)

is being executed after 在执行之后

this.ts = tsService.getTs();

In which case the behaviour is expected. 在这种情况下,行为是可以预期的。

As for how to deal with this problem. 至于如何处理这个问题。 One way is to add a way for components to subscribe to the service and get notified when ts changes so that they can react by executing some code. 一种方法是添加一种方法,使组件可以订阅服务并在ts更改时得到通知,以便它们可以通过执行一些代码来做出反应。 Look into RxJS' Subject . 看看RxJS的Subject

A different reason may be that you are not providing the service correctly. 另一个原因可能是您没有正确提供服务。

For example if you provide the service to a parent and a child component (direct or not). 例如,如果您向父级和子级组件(直接或不直接)提供服务。 In that case the second provider may be shadowing the first due to Angular's hierarchical dependency injection . 在那种情况下,由于Angular的层次依赖注入 ,第二个提供程序可能会遮盖第一个提供程序。 Which means that one component is setting the value in one instance of the service and the other component is getting it from a different one. 这意味着一个组件在服务的一个实例中设置值,而另一个组件从另一实例中获取值。 Unless you specifically need that kind of behaviour a service should only be provided at the root of the component tree where it's going to be used. 除非您特别需要这种行为,否则仅应在将要使用该组件树的根目录处提供服务。

If your components are not related through the parent-child hierarchy then you should be providing the service only once. 如果您的组件在父子层次结构中不相关,那么您应该只提供一次服务。 At the module level. 在模块级别。

Without knowing more about your component structure it's not possible to tell what exactly is going on. 如果不了解您的组件结构的更多信息,就不可能说出到底发生了什么。

As i can make out from your code. 正如我可以从您的代码中看出来的那样。 You have registered your service as a provider in your component. 您已经在组件中将服务注册为提供者。 like 喜欢

providers: [TsService]

What this line of code will do. 这行代码将做什么。 Is that it will fetch a new Instance of your service as soon as your component comes into play. 是它会在您的组件开始运行后立即获取服务的新实例。 So from first component lets say ComponentA you set the service variable as 因此,从第一个组件开始,假设ComponentA将服务变量设置为

this.tService.setTs(form.value.member)

But here ComponentA is having suppose Instnace1 of the service. 但是这里ComponentA假设服务的Instnace1。 So you have set the value to Instance1 of the Service. 因此,您已将该值设置为服务的Instance1。 Now you navigate to second component say ComponentB As soon as ComponentB comes into play it angular creates a new Instance of the service and same is made available to ComponentB . 现在,您导航到第二个组件,即ComponentB一旦ComponentB起作用,它就会创建一个新的服务实例,并且该实例可用于ComponentB Now there are two Instances of your service one with ComponentA and one with ComponentB . 现在,您的服务有两个实例,一个使用ComponentA ,另一个使用ComponentB but you have set the variable using ComponentA so it wont be available to ComponentB hence 但你已经使用设置变量ComponentA所以它不会提供给ComponentB因此

this.ts = this.tsService.getTs();

this returns undefined. 这将返回未定义。

In order to check whether you variable is set or not you can try 为了检查您是否设置了变量,可以尝试

this.tService.setTs(form.value.member);
console.log(this.tsService.getTs());

in your ComponentA it will log the value set. 在您的ComponentA ,它将记录该值集。

The solution for this problem of your is to share the same Instance and that can be achieved by registering the service as provider in the AppModule . 您的问题的解决方案是共享相同的实例,可以通过在AppModule服务注册为提供者来实现。

As official docs say 正如官方文档所说

On the one hand, a provider in an NgModule is registered in the root injector. 一方面,NgModule中的提供者在根注入器中注册。 That means that every provider registered within an NgModule will be accessible in the entire application. 这意味着在NgModule中注册的每个提供程序都可以在整个应用程序中访问。

For more please refer :- 有关更多信息,请参考:

Dependency Injection 依赖注入

NgModule Injectors NgModule注射器

Hope it helps :) 希望能帮助到你 :)

You may have use two instances of data object. 您可能使用了两个数据对象实例。 use one data service for set and get data.Then you can access to same data object within different components. 使用一个数据服务来设置和获取数据。然后,您可以访问不同组件中的同一数据对象。

And if you set that service as a provider for your components individually those gonna work as different instances. 而且,如果您将该服务分别设置为组件的提供者,则它们将作为不同的实例工作。 If you need only one instance for your whole app you can set that service as a provider in app.module.ts file. 如果整个应用程序仅需要一个实例,则可以在app.module.ts文件中将该服务设置为提供程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM