【问题标题】:angular dependency injection of one service into another for route guard将一个服务的角度依赖注入到另一个服务中以进行路由保护
【发布时间】:2018-03-03 02:30:36
【问题描述】:

在我的 Angular 应用程序中,我有两个服务,一个处理 http 层,另一个只是一个路由守卫,用于实现与第一个服务的状态相关的 canActivate 方法。例如:

后端服务:

@Injectable()
export class BackendService {
    private data: any;
    constructor(private http: Http) {
        console.log('backend service constructor hit');
        this.data = 'initial';
    }
    getData() {
        console.log(this.data);
        return this.data;
    }
    setData(data) {
        // http stuff
        this.data = data;
    }
}

routeguard.service:

@Injectable()
export class RouteguardService implements CanActivate {
    constructor(private backendService: BackendService) { }
    canActivate() {
        return this.backendService.getData() !== 'initial';
    }
}

我认为我在错误的位置提供了其中一项服务?目前,我的app.moduleproviders 数组中有这两项服务。但是我可以通过 console.log 语句判断 backend.service 在作为路由的一部分被调用时与组件使用它时是分开的,所以数据是不同的,并且数据总是返回为尽管已将其设置为来自组件的其他内容,但在 canActivate 方法中检查时为“初始”。希望我解释清楚了,我还是 Angular 的新手。

我是否需要在不同的位置提供其中一项服务,还是我完全做错了什么?感谢您的任何指点。

【问题讨论】:

  • 该问题不包含所有相关代码。请提供stackoverflow.com/help/mcve。使用您所指的组件和模块。
  • 您的应用程序中是否有多个模块?

标签: angular dependency-injection angular-routing angular-services angular-router-guards


【解决方案1】:

尝试将您要在BackendService 中设置的属性声明为static 之一。然后使用 getter 和 setter 来访问它。不要在服务的constructor中初始化。

@Injectable()
export class BackendService {
    private static data: any = 'initial';
    constructor(private http: Http) {
        console.log('backend service constructor hit');
    }
    get data() {
        console.log(this.data);
        return BackendService.data;
    }
    set data(data: any) {
        // http stuff
        BackendService.data = data;
    }
}

然后,您可以使用 getter 和 setter 在外部访问私有静态 data 值。例如在canActivate 守卫中,

@Injectable()
export class RouteguardService implements CanActivate {
    constructor(private backendService: BackendService) { }
    canActivate() {
        return this.backendService.data !== 'initial';
        // this.backendService.data <-- denotes getter
        // this.backendService.data = 'not-initial'; <-- denotes setter
    }
}

根据问题的理解,您在正确的地方提供服务。试试看能不能解决。

【讨论】:

    【解决方案2】:

    我意识到问题是我不小心将backend.service 包含在根app.component 提供程序中,这意味着它的子组件将注入一个实例,但是我的路由文件中的一个实例是从@987654323 注入的@ 提供程序,因此重复服务和数据差异。

    因此解决方案是从app.component 中删除该服务,并始终由app.module 提供它。

    【讨论】:

    • 只是指出,每次您在应用程序的任何位置注入此服务时,它都会创建一个与其关联的新数据属性,作为构造函数调用的一部分。请注意它,如果需要,那么没有问题。否则,或者换句话说,如果你想拥有一个与可从多个模块中访问的可注入服务关联的单例属性,那么你必须使用static 声明它。
    猜你喜欢
    • 2020-01-27
    • 2022-12-20
    • 1970-01-01
    • 2020-09-04
    • 2016-08-07
    • 1970-01-01
    • 2013-12-22
    • 2023-03-16
    相关资源
    最近更新 更多