Angular - 在 OnInit 上进行不同 API 调用的通用组件

Posted

技术标签:

【中文标题】Angular - 在 OnInit 上进行不同 API 调用的通用组件【英文标题】:Angular - Common Component making different API calls on OnInit 【发布时间】:2019-02-05 14:05:20 【问题描述】:

我有一个用例,其中两条不同的路线具有几乎完全相似的视图。要走的路(在我的理解中)是路由到同一个组件,从而重用它们。该组件基本上显示了可点击的项目列表。 唯一的问题是,我必须根据当前路由在同一组件的 OnInit 上调用不同的 API。在单击这些列表项时,我必须路由到不同的组件。例如,在路径“待办事项”中单击项目路由时如下所示:

path: 'todo',
            component: UserDesktopMainComponent,
            children: [
                
                    path: ':empLoginId/:formId',
                    component: EvaluationFormComponent
                ,
                
                    path: '',
                    component: EmptyComponentComponent
                ,

                
                    path: '**',
                    redirectTo: ''
                
            ]

从路径'历史'

path: 'history',
            component: HistoryDesktopComponent,
            children: [
                
                    path: ':empLoginId',
                    component: EvaluationDetailsComponent
                ,
                
                    path: '',
                    component: EmptyComponentComponent
                ,

                
                    path: '**',
                    redirectTo: ''
                
            ]

我想到的解决方案是在通过路由快照或在路由的数据部分传递关键字之前检查当前路由 onInit。然后在服务中,我可以从组件传递特定的关键字并相应地调用 API(我想知道是否有更优雅的方法来做到这一点)。对于点击路由,我可以调用一个组件函数,该函数将根据当前路由导航。目前,在模板中,我的路由如下:

<a *ngFor="let emp of employeeDisplayList" routerLink="'/todo/'+emp.employee.loginId+'/'+emp.evaluationFormMappingId"</a>

这可能不会让我按照我想要的方式路由。

我可能在这里遗漏了一些非常基本的概念,或者这可能是一个设计模式问题。 我想知道的是,如果有更好、更优雅的方法来解决上述所有问题,基本上可以重用组件。我不想将相同的代码从一个组件复制到另一个组件。

【问题讨论】:

【参考方案1】:

假设我理解这个问题,您想要一个两个页面上的可点击项目列表 - 但网址的构建方式不同。


制作一个新组件!

在 Typescript/javascript 中,函数是对象,因此我们可以将它们用作组件的输入参数。


可点击列表.ts

@Component(
    selector: 'my-clickable-list',
    templateUrl: './clickable-list.html',
    styleUrls: ['./clickable-list.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
)
export class ClickableListComponent<T> 
    @Input()
    public items: T[];

    @Input()
    public getUrl: (item: T) => string;

    constructor()

可点击列表.html

<div>
    <a *ngFor="let item of items" [routerLink]="getUrl(item)"</a>
</div>

UserDesktopMainComponent (HTML)

<my-clickable-list [items]="employeeDisplayList" [getUrl]="getTodoUrl"></my-clickable-list>

UserDesktopMainComponent (TS)

public getTodoUrl(emp: WhateverTypeThisIsSupposedToBe) 
    return "/todo/" + emp.employee.loginId + "/" + emp.evaluationFormMappingId;

HistoryDe​​sktopComponent (HTML)

<my-clickable-list [items]="employeeDisplayList" [getUrl]="getHistoryUrl"></my-clickable-list>

HistoryDe​​sktopComponent (TS)

public getHistoryUrl(emp: WhateverTypeThisIsSupposedToBe) 
    return "/history/" + emp.employee.loginId;

【讨论】:

我有点理解你的回答。所以为了澄清一下,用例就像 UserDesktopMainComponent 是我需要动态路由到 todo 组件或历史组件的主要组件(这两个是我在问题中提到的类似组件)。因此,您创建的可点击组件应该像您所做的那样注入历史组件,同样我将创建一个待办事项组件并将可点击组件插入其中,然后根据我的用户 UserDesktopMainComponent 路由到这两个组件网址。我的理解正确吗? 啊,我不明白这就是你要找的东西。我假设您希望 UserDesktopMain 路由到 EvaluationForm 和 HistoryDe​​sktop 路由到 EvaluationDetailsComponent。您可能不需要新组件来描述您所描述的内容,您可能可以使用与此答案类似的策略 - 将 routerLink 绑定到一个函数,然后应用您需要的任何逻辑来确定链接是否应该转到 ToDo 或历史

以上是关于Angular - 在 OnInit 上进行不同 API 调用的通用组件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.5 $onInit 未触发 - 打字稿

Angular2指令,构造函数与onInit [重复]

我不明白为啥 Angular 组件类 add 实现 onInit 接口

Angular 5在多个站点上进行生产构建部署

当我们谈论 OnInit 时,Angular 2+ 中组件初始化的确切含义是啥?

为啥 Angular Oninit 仅在离开页面时才调用服务