简体   繁体   English

我们如何从 ionic 4 中的 app.component 获取当前页面?

[英]how we can get the current page from app.component in ionic 4?

i am trying to get current page instance in app.component in ionic 4.我正在尝试在 ionic 4 中的 app.component 中获取当前页面实例。

in ionic 3 i can do it like this在离子 3 我可以这样做

this.nav.getActive().instance this.nav.getActive().instance

You can access the url from the Router.您可以从路由器访问该 url。

import { OnInit } from '@angular/core';
import { Router } from '@angular/router';

export class YourPage implements OnInit {
   constructor(private router: Router) {}

   ngOnInit() {
        console.log('this.router.url', this.router.url);
    }
}

I'm in a similar situation.我处于类似的情况。 In a multi-page application, I need the instance of the current class component.在多页应用程序中,我需要当前类组件的实例

Basically, I have a modal that can open on each page and ask the user if she wants to reload data or not.基本上,我有一个模式可以在每个页面上打开并询问用户是否要重新加载数据。 When the user chooses yes , I want to reach the current page instance and call a reload method on it.当用户选择yes 时,我想访问当前页面实例并对其调用重新加载方法。

I ended up with this dirty trick.我结束了这个肮脏的把戏。 I'm not an Angular/JS/Ionic expert, so probably there are better and cleaner ways to do this.我不是 Angular/JS/Ionic 专家,所以可能有更好、更干净的方法来做到这一点。 Use this at your own risk, in my situation it seems to work , although not perfectly (see later).使用它需要您自担风险,在我的情况下它似乎可以工作,尽管并不完美(见下文)。

The idea想法

My idea is simple: when a new page component class is instantiated (constructor called), I bind it to the url used to navigate to it .我的想法很简单:当一个新的页面组件类被实例化(构造函数调用)时,我将它绑定到用于导航到它的 url。

Class instantiation happens before navigation ends, so when navigation end event occurs, I use the final url to get back the instance.类实例化发生在导航结束之前,所以当导航结束事件发生时,我使用最终 url 来取回实例。

Code代码

Invoking code from current page从当前页面调用代码

In my app.component.ts , I put the event handler with the call to the page component methods:在我的app.component.ts ,我将事件处理程序与对页面组件方法的调用一起放置:

export class AppComponent implements OnInit {
  private navEnd: Observable<NavigationEnd>;

  constructor(
    // ... other dependencies
    private router: Router,
    private routeMap: RouteMap // this is my class, see later
  ) {

    this.navEnd = router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ) as Observable<NavigationEnd>;
  }

  ngOnInit() {
    this.navEnd.subscribe(evt => {
      let instance = this.routeMap.getObject(evt.urlAfterRedirects);
      if (instance != null) {
        instance.doStuff();
        // ... or save instance elsewhere, like
        //   this.aService.setCurrentPage(instance);
        // or anything you need
      }
    });
  }
}

In the subscribe call, I use evt.urlAfterRedirects instead of evt.url to handle the case when the empty path redirects to the first page, like this (in app-routing.module.ts ):subscribe调用中,我使用evt.urlAfterRedirects而不是evt.url来处理空路径重定向到第一页的情况,如下所示(在app-routing.module.ts ):

const routes: Routes = [
  { path: '', redirectTo: 'categories', pathMatch: 'full' },
  { path: 'home', loadChildren: './pages/home/home.module#HomePageModule' },
  { path: 'page1', loadChildren: './pages/page1/page1.module#Page1PageModule' },
  // ...
];

If you have a similar configuration, when you navigate / and the NavigationEnd event occurs, evt.url is / and evt.urlAfterRedirects is /home .如果你有类似的配置,当你导航/并且NavigationEnd事件发生时, evt.url/evt.urlAfterRedirects/home

When you navigate to /page1 and then go back to home page using the back button, when NavigationEnd occurs, both evt.url and evt.urlAfterRedirects are /home .当您导航到/page1然后使用后退按钮返回主页时,当NavigationEnd发生时, evt.urlevt.urlAfterRedirects都是/home

To be sure that in both cases I get the instance, I need to user urlAfterRedirects .为了确保在这两种情况下我都能获得实例,我需要使用urlAfterRedirects

Tracking current page跟踪当前页面

In my pages, I change the constructors like this:在我的页面中,我像这样更改构造函数:

export HomePageComponent implements OnInit {
  constructor(
    private router: Router,
    private routeMap: RouteMap // again my code
  ) {
    routeMap.registerObject(router.getCurrentNavigation().finalUrl.toString(), this);
  }

  // ...
}

Basically, when the constructor is called, I know the instance of the component class, so I bind it to the current url.基本上,当构造函数被调用时,我知道组件类的实例,所以我将它绑定到当前 url。

This code is quite rough, probably it's better to factorize it out, making a superclass, a decorator, a mixin, so that you don't have to duplicate the code on each page.这段代码相当粗糙,可能最好将其分解,制作一个超类,一个装饰器,一个mixin,这样您就不必在每个页面上复制代码。 Being not a Javascript or Angular expert, here I'm a bit lost.由于不是 Javascript 或 Angular 专家,在这里我有点迷茫。 I would go with a superclass (because I just know them), but probably it's better something else.我会选择一个超类(因为我只知道它们),但可能它是其他更好的东西。

The RouteMap code RouteMap代码

This is where tracking happens.这就是跟踪发生的地方。 It is a little service you can put where you like.这是一项小服务,您可以将其放在您喜欢的位置。

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RouteMap {
  private map: {
    path: string,
    object: object
  }[] = [];

  getObject(path: string) {
    let item = this.map.find(function (item) {
      return item.path == path;
    });

    return item ? item.object : null;
  }

  registerObject(path: string, object: object) {
    let item = this.map.find(function (item) {
      return item.path == path;
    });

    if (item) {
      item.object = object;
    } else {
      this.map.push({
        path: path,
        object: object
      });
    }
  }
}

The registerObject() first check if the given path has already been mapped to an object. registerObject()首先检查给定的path是否已经映射到一个对象。 If that is the case, it just update the object, so that you don't have duplicated paths.如果是这种情况,它只会更新对象,这样您就没有重复的路径。 Otherwise, it adds a new entry in the map.否则,它会在地图中添加一个新条目。

The getObject() searches the map for the give path and gives the registered object if the path exists. getObject()在地图中搜索给定path并在路径存在时提供注册对象。 Otherwise it gives null .否则它给出null

Issues问题

Bad behavior with first tab in tabbed view选项卡式视图中第一个选项卡的不良行为

In my case, I have a sequence of pages Home -> Page1 -> ... -> PageN -> TabbedPage where the last is a page that has 3 tabs.在我的例子中,我有一系列页面Home -> Page1 -> ... -> PageN -> TabbedPage其中最后一个是一个有 3 个选项卡的页面。

TabbedPage has this routing definition: TabbedPage具有以下路由定义:

const routes: Routes = [
  {
    path: '',
    component: TabbedPage,
    children: [
      {
        path: '',
        redirectTo: 'tab1',
        pathMatch: 'full'
      },
      {
        path: 'tab1',
        children: [{
          path: '',
          loadChildren: './tab1/tab1.module#Tab1Module'
        }]
      },
      {
        path: 'tab2',
        children: [{
          path: '',
          loadChildren: './tab2/tab2.module#Tab2Module'
        }]
      },
      {
        path: 'tab3',
        children: [{
          path: '',
          loadChildren: './tab3/tab3.module#Tab3Module'
        }]
      },
    ]
  },
];

so when I navigate to /tabbedpage , it automatically opens the /tabbedpage/tab1 tab.所以当我导航到/tabbedpage ,它会自动打开/tabbedpage/tab1选项卡。

However, I noticed that if I try to track the Tab1 instance with但是,我注意到如果我尝试跟踪Tab1实例

export class Tab1 implements OnInit {

  constructor(
    private router: Router,
    private routeMap: RouteMap
  ) {
    routeMap.registerObject(router.getCurrentNavigation().finalUrl.toString(), this);
  }

}

it does not work: getCurrentNavigation() gives null .它不起作用: getCurrentNavigation()给出null I logged the navigation events and I've noticed that no navigation occurs from TabbedPage to Tab1 .我记录了导航事件,我注意到从TabbedPageTab1没有导航发生 Tab1 is just instantiated. Tab1只是实例化。

So I have this sequence of events:所以我有这样的事件序列:

  • navigation starts to /tabbedpage导航开始到/tabbedpage
  • (internal) redirect from /tabbedpage to /tabbedpage/tab1 found (内部)从/tabbedpage重定向到/tabbedpage/tab1 found
  • TabbedPage is created and bound to /tabbedpage/tab1 TabbedPage被创建并绑定到/tabbedpage/tab1
  • navigation ends from /tabbedpage to /tabbedpage/tab1导航从/tabbedpage结束到/tabbedpage/tab1
  • Tab1 is created Tab1已创建

After that, if I navigate the other tabs, the instances of Tab2 and Tab3 are correctly bound to /tabbedpage/tab2 and /tabbedpage/tab3 .之后,如果我导航其他选项卡,则Tab2Tab3的实例将正确绑定到/tabbedpage/tab2/tabbedpage/tab3 If I navigate back to Tab1 , I get the instance of TabbedPage .如果我导航回Tab1 ,我会得到TabbedPage的实例。


At the moment I have not found other particular issues, but the code is enough for my case.目前我还没有发现其他特定问题,但代码对我来说已经足够了。

Let see if it is useful to you too.看看它是否对你也有用。

Bye再见

I did this one and it works for me:我做了这个,它对我有用:

ionViewWillEnter() {  
   console.log(this.router['routerState'].snapshot.url);
}

in my case I used an observable to solve this situation就我而言,我使用了一个 observable 来解决这种情况

here's my url Service这是我的网址服务

@Injectable({
  providedIn: 'root'
})
export class CurrentPageService {
  private $urlParts:BehaviorSubject<any>;
  private url;
  constructor(private router:Router) { 
    this.$urlParts = new BehaviorSubject(null);
  }
  get urlParts(){
    return this.$urlParts.asObservable();
  }
  setUrl(){
    this.url=this.router.url;
    let parts = this.url.split('/');
    return this.$urlParts.next(parts);
  }
}

and any page that I'm interested in getting its currently active state in my app component i trigger this observable以及我有兴趣在我的应用程序组件中获取其当前活动状态的任何页面,我都会触发此 observable

export class HomePage {
  constructor(private currentPage:CurrentPageService) {

  }
ionViewDidEnter(){
  this.currentPage.setUrl();
}

and finally in my appcomponent最后在我的应用程序组件中

export class AppComponent {
urlParts;
constructor(private currentpage:CurrentPageService){
      this.currentPage.urlParts.subscribe(url=>this.urlParts=url);
    });
}
foo(){
        if (!this.urlParts.includes('home')) {
          //do something
        }
}

}

u can track the current page using the routeroutlet你可以使用routeroutlet跟踪当前页面

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

check documentation for more info https://angular.io/api/router/RouterOutlet检查文档以获取更多信息https://angular.io/api/router/RouterOutlet

In Ionic 4 use below code to get current page name using NavController在 Ionic 4 中,使用以下代码使用NavController获取当前页面名称

import { NavController } from '@ionic/angular';

constructor(public navCtrl: NavController) {

}

ngOnInit() {
    console.log(this.navCtrl.router.routerState.snapshot.url)
}

Hope this will helps!希望这会有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM