如何在具有多个组件/路由的ngOnInit上调用服务的方法



我有几个路由只是一个静态页面。
在每条路由(超过50条)上,当路由初始化时,我必须在两个不同的服务上调用几个方法(甚至更多)。
一个简单的工作解决方案是在每个页面上调用ngOnInit方法并调用前面提到的方法。问题是,这意味着在50个不同的文件上复制和粘贴相同的代码。复制和粘贴是不好的,它是不可维护的。

举例:

我有页面"FAQ"(手动分配id: 52)和页面"Find Us"(手动分配id: 13)。这是两条不同的路线。
我有"编辑器"服务,用于从管理面板编辑这些页面,它需要跟踪我看到的页面。
我有服务"缓存",检查页面是否已经查询到后端之前,或者如果它需要从服务器拉出。
这两个服务都想知道我手动分配给该路由的ID。
这个特定情况下的ID用于查询数据库/API,但是这个细节不是以问题为中心的,不应该使其他有类似问题的人的答案无效。

// Page FAQ
id: number
constructor() {
  this.id = 52; // 52 is the id that I assigned to the page FAQ
}
ngOnInit () {
  editorService.keepTrack(this.id);
  editorService.moreMethod().notMaintainable().whatIfIChangeSomething(this.id/0);
  cacheService.keepTrack(this.id);
}
// Page Find Us
id: number
constructor() {
  this.id = 13; // 13 is the id that I assigned to the page Find Us
} 
ngOnInit () {
  editorService.keepTrack(this.id);
  editorService.moreMethod().notMaintainable().whatIfIChangeSomething(this.id/0);
  cacheService.keepTrack(this.id);
}

现在,这是一个简化的例子,因为我认为没有必要用与手头问题无关的细节来超载问题。

我能想到的唯一解决办法就是做第三项服务。这将调用其他两个的方法。
所以在每个页面中,我只需要在ngOnInit上调用这一个服务方法,而把如何调用其他两个服务方法的实现留给第三个服务。
这将最大限度地减少复制和粘贴,并将实现留在单个可维护的文件中。

举例:

// Page FAQ v2
id: number
constructor() {
  this.id = 52;
}
ngOnInit() {
  inceptionService.doStuff(this.id);
}
// Page Find Us v2
id: number
constructor() {
  this.id = 13;
}
ngOnInit() {
  inceptionService.doStuff(this.id);
}
// InceptionService
export class InceptionService {
  doStuff(data) {
  editorService.keepTrack(data);
  editorService.moreMethod().notMaintainable().whatIfIChangeSomething(data/0);
  cacheService.keepTrack(data);
  }
}

问题是:
有更好的方法吗?我有一种感觉,我没有使用最好的方法。
我还是觉得我在滥用服务。

你可以为这些路由创建一个基类,并让你的组件继承这个基类。

export class BaseComponent {
    ngOnInit() {
        //your service calls
    }
}
export class MyStaticComponent1 extends BaseComponent {
    ngOnInit() {
        super.ngOnInit();
        //component specific calls
    }
}

你可以订阅路由事件并从那里调用你的方法。(参见如何在Angular 2中检测路由变化?)

michael Dymel的替代方案是有效的,并且可以用比我的"InceptionService"更好的方法满足我的所有需求,但是我觉得g nter Zöchbauer的答案使用了更好、更可维护和更Angular的方法,尽管他的答案不完整。
g nter Zöchbauer的答案也让我找到了Alex Rickabaugh @alxhub帮助我最终确定的另一个解决方案。

这里我指的是angular-cli结构。

on app.component.html replace
<router-outlet>

<router-outlet (activate)="newComponentActivated($event)">

在app.component.ts

newComponentActivated(component) {
  // Updating tracked page ID
  this.editorService.updateCurrentPage(component);
}

在"editor service"

updateCurrentPage(component) {
  console.log(component);
}

现在,每当路由发生变化时,一个事件就会用组件的副本通知编辑器服务,包括参数和方法。
这意味着不需要在路由组件中扩展或实现任何东西。

最新更新