Angular 如何调用服务';具有多个组件/路由的ngOnInit上的s方法
我有几条路线只不过是一个静态页面。Angular 如何调用服务';具有多个组件/路由的ngOnInit上的s方法,angular,implements,Angular,Implements,我有几条路线只不过是一个静态页面。 在每一条路由(超过50条)上,当路由启动时,我必须在两个不同的服务上调用两个(或更多)方法。 一个简单的工作解决方案是,在每个页面上,我调用ngOnInit方法并调用前面提到的方法。 问题是,这意味着在50个不同的文件上复制和粘贴相同的代码。复制和粘贴不好,不可维护 举个例子: // Page FAQ v2 id: number constructor() { this.id = 52; } ngOnInit() { inceptionService.
在每一条路由(超过50条)上,当路由启动时,我必须在两个不同的服务上调用两个(或更多)方法。
一个简单的工作解决方案是,在每个页面上,我调用ngOnInit方法并调用前面提到的方法。
问题是,这意味着在50个不同的文件上复制和粘贴相同的代码。复制和粘贴不好,不可维护 举个例子:
// 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);
}
}
我有页面“常见问题解答”(手动分配id:52)和页面“查找我们”(手动分配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
}
}
Michal Dymel的替代方案是有效的,可以用一种比我的“接收服务”更好的方法满足我的所有需求,但我觉得Günter Zöchbauer的回答使用了一种更好、更易维护和更具角度的方法,尽管他的回答不完整。
Günter Zöchbauer answer还为我提供了帮助,让我找到Alex Rickabaugh@alxhub帮助我最终确定的另一个解决方案 这里我指的是角度cli结构 在app.component.html上替换
与
在app.component.ts上
newComponentActivated(component) {
// Updating tracked page ID
this.editorService.updateCurrentPage(component);
}
在“编辑服务”中
现在,每次路由更改时,一个事件都会通知编辑器服务组件的副本,包括参数和方法。这意味着不需要在路由组件中扩展或实现任何内容。如果您可以发布一些代码来演示您在
ngOnInit()
中所做的事情,那么就更容易理解了。我添加了这个示例。52
和13
来自哪里?您是否需要该组件,或者是否有一种方法可以像全局服务一样在顶级获得该组件?“52”和“13”是要在数据库上查询的ID。它们是手动分配给组件的,但可能只是路由本身的名称,如“常见问题解答”和“查找我们”。目前,这些信息存储在组件中,但如果我找到另一种方法,绝对不需要坚持。我喜欢这种方法,我只发现它的局限性在于我不能硬编码(或读取硬编码)组件中的内容。例如,我不能使用数字作为ID来查询数据库。我必须使用该路线,如果我想将路线从“为傻瓜学习英语”更改为“为阿拉丁学习阿拉丁”,这可能是一个问题,因为我还必须更改DB中的引用。警卫可能也适用于此,组件类型也可从路线获得。应该有一些方法可以获取例如静态值或调用这些组件上的静态方法。我无法让警卫从组件获取属性或方法,您能举个例子吗?使用canActivate(route:ActivatedRouteSnapshot,state:routerstatesnashot):布尔值{
路由有一个组件
属性。我不知道这个组件引用可以做什么,也不知道你需要用它做什么(不太清楚)。我试过了,但什么都没有,正如Alex Rickabaugh@alxhub指定的:“不,因为canActivate正在决定组件是否可以实际实例化,所以还没有实例。”他表示,我们无法看到组件内部使用的数据或方法。router.events也没有帮助,但我发现了一种不同的方法,可以满足基于此的所有需求(请参阅我的答案,我仍在键入它)。这种方法的问题是,我不能再在组件内部为组件的特定任务使用ngOnInit。如果我这样做,我将失去扩展的ngOnInit,并且无法从扩展中获益。由于ngOnInit是一种特定于Angular2的方法,我宁愿滥用服务,也不愿处理此约束。您可以调用super.ngOnInit()
,然后执行特定任务