Angular服务被实例化两次?

8
一些我所使用的服务似乎被实例化了两次(它的属性不同步),可能是因为我进行了以下操作:
@Component
export class MyComponent extends someOtherComponent {
  constructor(service: Service, service2: Service2) {
    super(service, service2);
  }

  isStateEqual() {
    return this.service.serviceState === this.service2.service.serviceState;
  }
}

@Injectable
export class Service {
  serviceState = {}
}

@Injectable
export class Service2 {
  constructor(service: Service) {}
}

这只是一个非常基础的例子,但这正是所涉及到的。更确切地说:我们正在构建自己的日期选择器,并扩展NgbDatepicker组件,该组件具有KeyMapService(使用NgbDatepickerService)和本地NgbDatepickerService。
以下是组件链接:https://ng-bootstrap.github.io/#/components/datepicker/examples

在我们的应用中,isStateEqual总是返回false(即使在初始化组件后立即执行),而在上面链接中的演示中它总是返回true(应该是这样的)。任何人都知道为什么会这样吗?感谢您的帮助。

祝好, Dennis

1
这是伪代码吗?为什么在装饰器后面不使用括号呢? - Pavel Agarkov
当然只是伪代码。把整个东西放在这里会相当多。 - Schadenn
你能提供一个 StackBlitz 吗? - Aamir Khan
你可以尝试从service2中获取service1,而不是直接注入它作为一种解决方法。为了全面了解情况,我们需要查看您的提供程序声明。 - Pavel Agarkov
@Eliseo 我们有一个datepicker.module.ts文件,其中我们提供了两个服务。 - Schadenn
显示剩余4条评论
5个回答

5
应用程序范围的单例必须在引导模块上定义:
platformBrowserDynamic()
  .bootstrapModule(AppModule)

@NgModule({
  providers: [SingletonService1, SingletonService2],
  bootstrap: [AppComponent]
})

export class AppModule {}

来源

或者在服务装饰器上设置 providedIn: 'root'

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

来源


5
在我的情况下,服务被实例化了两次,因为我使用了两种不同的方式导入了服务(我的IDE(VS2019)自动产生了错误的导入,导致我困惑了)。
import { Service } from '@mycompany/mymodule' 

import { Service } from '../../../dist/@mycompany/mymodule/@mycompany-mymodule';

3
Visual Code可以自动以以下方式导入我的服务:
import { ConfigService } from 'src/app/services/config.services.js';

正确的方法是:

import { ConfigService } from 'src/app/services/config.services';

0

这取决于您在哪里声明服务提供程序 - 这决定了作用域。您的问题中没有指定您在哪里进行了此操作 - 例如,尝试在 AppModule 中进行。


抱歉。我们有一个datepicker.module.ts文件,其中提供了两个服务(service和service2)。 - Schadenn
我猜这可能与服务提供的位置有关。正如我所说,它们在我们的datepicker.module中,但它们也在我们正在扩展的NgbDatepicker组件中提供。不幸的是,如果我暂时从外部组件中删除提供程序,它仍然无法正常工作。但这可能就是问题所在。 - Schadenn
如果在您的组件中使用了提供者,那么它会创建服务的新实例。在这种情况下,我认为没有什么可做的。 - Eliseo

-1

“service” 必须是 Service2 的公共属性。

@Injectable
export class Service2 {
  service:Service
  constructor(service: Service) 
  {
      this.service=service;
  }
}

其实这是一个私有属性。我将其更改为公共属性以使我的“isStateEqual()”函数正常工作,但我不能这样做,因为我会修改外部库。抱歉,我在伪代码中没有写明这一点。 - Schadenn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接