Angular 2 output from router-outlet

后端 未结 4 2083
野的像风
野的像风 2020-11-29 01:05

I want to make navigation from child components that render inside router-outlet. My parent component have a router config and I want to navigate manually on some event. But

相关标签:
4条回答
  • 2020-11-29 01:27

    The answer given above is correct and complete. I just want to add for those who the solution didn't work for them that they should add the service to providers only in the parent component and not the child to ensure that you get a singleton of the service, otherwise two service instances will be created. This response is inspired by the comment of @HeisenBerg in the previous response.

    0 讨论(0)
  • 2020-11-29 01:38

    I changed a little from Antara Datta's answer. I created a Subscriber service

    import {Injectable} from '@angular/core';
    import {Subject} from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class Subscriber<T>
    {
      protected observable = new Subject<T>();
    
      public next(item: T)
      {
        this.observable.next(item);
      }
    
      public subscribe(callback: (item:T)=>void) {
        this.observable.subscribe(callback);
      }
    }
    

    Whenever I need two components to share some information, I inject this service in the constructor which subscribe to it:

     constructor(protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
     {
        layoutOptions.subscribe(options => this.options = Object.assign({}, this.options, options));
     }
    

    and the one which updates it

    constructor(protected router: Router, protected apiService: ApiService, protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
      {
        this.layoutOptions.next({showNavBar: false});
      }
    
    0 讨论(0)
  • 2020-11-29 01:40

    <router-outlet></router-outlet> is just a placeholder for adding routed components. There is no support for any kind of binding.

    You can create a custom <router-outlet> that allows you to do that or more common, use a shared service to communicate between parent component and routed component.

    For more details see https://angular.io/docs/ts/latest/cookbook/component-communication.html

    update

    There is now an event that allows to get the added component

    <router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet>
    

    which allows to communicate (call getters, setters, and methods) with the component in componentAdded()

    A shared service is the preferred way though.

    0 讨论(0)
  • 2020-11-29 01:47

    <router-outlet></router-outlet> can't be used to emit an event from the child component. One way to communicate between two components is to use a common service.

    Create a service

    shared-service.ts

    import { Observable } from 'rxjs/Observable';
    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs/Subject';
    @Injectable()
    export class SharedService {
        // Observable string sources
        private emitChangeSource = new Subject<any>();
        // Observable string streams
        changeEmitted$ = this.emitChangeSource.asObservable();
        // Service message commands
        emitChange(change: any) {
            this.emitChangeSource.next(change);
        }
    }
    

    Now inject the instance of the above service in the constructor of both the parent and child component.

    The child component will be emitting a change every time the onClick() method is called

    child.component.ts

    import { Component} from '@angular/core';
    @Component({
        templateUrl: 'child.html',
        styleUrls: ['child.scss']
    })
    export class ChildComponent {
        constructor(
            private _sharedService: SharedService
        ) { }
    
    onClick(){
      this._sharedService.emitChange('Data from child');
    
     }
    }
    

    The parent component shall receive that change. To do so,capture the subscription inside the parent's constructor.

    parent.component.ts

    import { Component} from '@angular/core';
    @Component({
        templateUrl: 'parent.html',
        styleUrls: ['parent.scss']
    })
    export class ParentComponent {
        constructor(
            private _sharedService: SharedService
        ) {
              _sharedService.changeEmitted$.subscribe(
            text => {
                console.log(text);
            });
          }
    
    }
    

    Hope this helps :)

    0 讨论(0)
提交回复
热议问题