Can you use @ViewChild() or similar with a router-outlet? How if so?

▼魔方 西西 提交于 2019-12-17 20:04:04

问题


I repeatedly run into a situation where I'd like to access a child component existing on the other side of a router outlet rather than a selector:

Like:
<router-outlet></router-outlet>

NOT:
<selector-name></selector-name>

This conflicts with the ViewChild functionality as I know it, yet it seems like my component should be able to see and interact with what's inside that router-outlet just as easily as with what's inside a selector-tag.

For instance I tried this:

export class RequestItemCatsComp {
    @ViewChild('child') child: RequestItemsComp;
    ***etc...***
ngAfterViewInit() {
    if (this.child) // Always child is undefined
        this.groupId = this.child.groupId;
    }
}

But naturally, child is undefined because this is the wrong way. Is there a right way?

I'm trying to use a service to share the data but then run into another problem "expression has changed after it was checked" which I'm hoping to remedy without a hack or enabling prod mode.


回答1:


You may tap into activate event to get reference of instantiated component inside the router outlet.

excerpt from RouterOutlet Docs

A router outlet will emit an activate event any time a new component is being instantiated, and a deactivate event when it is being destroyed.

example

 @Component({
  selector: 'my-app',
  template: `<h3 class="title">Basic Angular 2</h3>
  <router-outlet (activate)="onActivate($event)" ></router-outlet>
  `
})
export class AppComponent {
  constructor(){}

  onActivate(componentRef){
    componentRef.sayhello();
  }
}

@Component({
  selector: 'my-app',
  template: `<h3 class="title">Dashboard</h3>
  `
})
export class DashboardComponent {
  constructor(){}

  sayhello(){
    console.log('hello!!');
  }
}

Here is the Plunker!!

Hope this helps!!




回答2:


The approach by Madhu works if you are not reattaching to a route. It appears that activate does not get run on the re-route.

There is a read only property on router-outlet that contains the current component.

example:

 @Component({
  selector: 'my-app',
  template: `<h3 class="title">Basic Angular 2</h3>
  <button (click)="identifyYourself()"></button>
  <router-outlet></router-outlet>
  `
})
export class AppComponent {
  @ViewChild(RouterOutlet) outlet;
  constructor(){}

  identifyYourself() {
    if (outlet && outlet.component) {
      outlet.component.identify();
    }
  }
}

@Component({
  selector: 'my-app',
  template: `<h3 class="title">Dashboard</h3>
  `
})
export class DashboardComponent {
  constructor(){}

  identify(){
    console.log('Hello, I'm the dashboard!');
  }
}


来源:https://stackoverflow.com/questions/39255311/can-you-use-viewchild-or-similar-with-a-router-outlet-how-if-so

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!