【问题标题】:Angular 2 store component classes in serviceAngular 2 在服务中存储组件类
【发布时间】:2016-07-21 11:19:24
【问题描述】:

我想创建一个存储角度组件对象的服务。该服务基本上会有一个类似于{key: componentClass} 的属性组件。

实现起来似乎很简单,实际上也很简单,但是我遇到了一个问题,我不知道如何解决。

让我们呼叫服务ComponentStoreService。例如,它可能如下所示:

@Injectable()
export class ComponentStoreService {
 components: { [key: string]: any; } = {};

   register(key: string, components: any): void {
     this.components[key] = components;
   }

   getByKey(key: string): any {
     return this.components[key];
   }

   getAll(): any {
     return this.components;
   }
}

现在让我们创建 2 个演示组件并存储它们。:

const providers = ReflectiveInjector.resolve([ComponentStoreService]);
const injector = ReflectiveInjector.fromResolvedProviders(providers);
const componentStore= injector.get(ComponentStoreService );

@Component({
  selector: 'component-1',
  template: `<h2>component-1</h2>`
})
export class D1Component {constructor() {}}

componentStore.register('component-1', D1Component );

console.log('component-1 called', componentStore.getAll())

第二个:

    const providers = ReflectiveInjector.resolve([ComponentStoreService]);
    const injector = ReflectiveInjector.fromResolvedProviders(providers);
    const componentStore= injector.get(ComponentStoreService );

    @Component({
      selector: 'component-2',
      template: `<h2>component-2</h2>`
    })
    export class D2Component {constructor() {}}

    componentStore.register('component-2', D2Component );

    console.log('component-2 called', componentStore.getAll())

因此,第一个 console.log 打印对象,其中添加了第一个组件。没关系。第二个console.log 仅打印第二个组件。这是不正确的。

据我了解,每个组件 ComponentStoreService 是单独的实例。我怎样才能使它在整个应用程序中成为单例?我只在应用程序级别注册ComponentStoreService。这意味着问题出在其他地方。也许是因为我在组件类之外调用服务。

【问题讨论】:

  • 你得到的对这段代码是正确的:你创建了两个注入器,所以你得到了用它们注册的不同实例。真正的问题是——你试图通过这个实现的目标是什么?好像不太对。在我看来,人们不应该需要这样的机制。
  • 我需要实现一个功能,该功能可以仅显示存储在config.json 中的componentId 的那些组件。所以我想也许有可能有一个带有{ key: componentClass } 的对象,其中存储了所有组件。它可以通过键检索组件并仅呈现Ids 存储在config.json 中的那些组件。
  • 您必须了解该技术有局限性,例如这样您将无法管理组件模板中使用的管道,并且您将无法在模板中使用这些组件本身。除此之外,有可能实现你想要的,但我需要一些时间来为你准备答案。
  • 我不知道管道,但是关于在模板中使用组件你错了。您可以使用 ComponentResolver 动态呈现组件。示例在这里stackoverflow.com/questions/36325212/…

标签: angularjs angular angular2-services


【解决方案1】:

您的 ComponentStoreService 是全局服务。因为您在多个组件中使用该服务。您可以在应用程序加载时注入 1 次。因此您可以在任何地方使用它。

bootstrap(AppComponent, [ComponentStoreService]);

组件 1:

    @Component({
      selector: 'component-1',
      template: `<h2>component-1</h2>`
    })
    export class D1Component {constructor(private _componentStoreService:ComponentStoreService) {}}

    componentStore.register('component-1', D1Component );

    console.log('component-1 called', this._componentStoreService.getAll())

组件2

        @Component({
          selector: 'component-2',
          template: `<h2>component-2</h2>`
        })
        export class D2Component {constructor(private _componentStoreService:ComponentStoreService) {}}

        componentStore.register('component-2', D2Component );

        console.log('component-2 called', this._componentStoreService.getAll())

您可以使用提供程序来注入 ComponentStoreService 。

【讨论】:

  • 你应该知道这样每个组件都有自己的ComponentStoreService。如果您想共享服务,您需要在共享父级上提供它 - 例如AppComponent
  • 是的,只在根组件的providers 属性中使用ComponentStoreService 并将其注入您要注册的每个组件中。 stackoverflow.com/questions/34929665/…
  • 我通常也倾向于建议在bootstrap() 提供它,因为它更明显地表明它适用于整个应用程序,但是 Angular2 样式指南建议使用根组件的 providers 数组@ 987654330@。除了例如当前路由器 需要bootstrap() 上提供之外,行为没有太大区别
  • 但是我需要在组件类之外调用服务。这意味着我不能在组件内使用提供程序。我试图使用ReflectiveInjector,因为我想在组件之外获取服务实例。这是必需的,否则在编译时将不会调用服务方法,并且不会将组件对象存储在服务中。
猜你喜欢
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 2019-02-04
  • 2016-03-25
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多