我正在构建一个移动应用程序,我希望用户能够通过设置页面设置他们的起始页。这个想法是用户可以从选项列表中选择一个页面,设置将存储到本地存储中,稍后,当用户重新登录时,用户首先会自动转到该页面。
我有一个页面服务,其中包含 Id 到页面组件的映射。这是我用来在读取用户保存的起始页数据时查找要使用的页面的方法。
我的问题是我已经开发了一种循环依赖关系,我认为如果不找到一种不涉及使用注入组件的 Ionic2 路由方法,我就无法打破这种依赖关系。据我所知,在 Ionic2 中实现路由的唯一方法是使用 NavController.push(component( 或 Nav.setRoot(component(。
PageService.ts
import {Injectable} from "@angular/core";
import {HomePage} from "../pages/home/home";
import {SettingsPage} from "../pages/settings/settings";
import {CartPage} from "../pages/cart/cart";
@Injectable()
export class PageService {
public pages = [
{
id: "HOME",
component: HomePage
}, {
id: "SETTINGS",
component: SettingsPage
}, {
id: "CART",
component: CartPage
}
];
constructor() {
}
getPageById(id: string) {
return this.pages.find(page => (page.id === id));
}
}
设置.ts:
我的设置页面组件注入了页面服务,以便它可以访问以获取页面列表。这就是我的周期性依赖发生的地方。设置页面正在注入页面服务,其中包含对设置页面的引用。
import {Component} from "@angular/core";
import {PageService} from "../../providers/page-service";
import {UserService} from "../../providers/user-service";
@Component({
selector: "page-settings",
templateUrl: "settings.html",
})
export class SettingsPage {
startPages = [];
constructor(private pageService: PageService, private userService: UserService) {
this.startPages = this.pageService.getStartPages();
}
}
设置.html:
只是一个带有卡片的简单列表来输出选择。
<ion-content padding>
<ion-list>
<ion-card padding>
<ion-card-title>Starting Page</ion-card-title>
<ion-item>
<ion-select [(ngModel)]="userService.activeUser.startPage">
<ion-option *ngFor="let page of startPages" value="{{page.id}}">
{{page.id}}
</ion-option>
</ion-select>
</ion-item>
</ion-card>
</ion-list>
</ion-content>
。最后,当应用程序启动并且我想自动转到我的起始页时,我执行以下操作:
const startPage = this.pageService.getPageById(this.userService.activeUser.startPage);
this.nav.setRoot(startPage.component);
更新了答案
在设置页构造函数中使用正向引用。
constructor(@Inject(forwardRef(() => PageService)) private pageService: PageService) {
this.startPages = this.pageService.getStartPages();
}
旧答案- 不合适,因为 angular 应该通过注入来处理服务的实例化。"新"是一个坏主意(但它确实有效(。
我更改了在设置页面中加载页面服务的方式,并解决了循环依赖关系。我将PageService代码移出构造函数,并将其放入ngAfterViewInit((函数中。现在,页面服务仅在加载视图时实例化。
ngAfterViewInit(){
this.pageService = new PageService();
this.startPages = this.pageService.getStartPages();
}