来自路由器插座的 Angular 2 输出



我想从在路由器出口内呈现的子组件进行导航。我的父组件有一个路由器配置,我想手动导航某些事件。但是我不知道如何在没有输出的情况下将一些数据(用于导航)从子级传递到父级。因为这种结构是非工作的

 <router-outlet (navigateTo)="navigateToMessagePart($event)"></router-outlet>

我怎样才能以正确的方式做到这一点?也许从孩子那里导航它?但是我如何从孩子那里获得父母的方法。非常感谢任何帮助!

<router-outlet></router-outlet>不能

用于从子组件发出事件。在两个组件之间进行通信的一种方法是使用公共服务。

创建服务

共享服务.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);
    }
}

现在,在父组件和子组件的构造函数中注入上述服务的实例。

每次调用 onClick() 方法时,子组件都会发出更改

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");
    }
}

父组件应收到该更改。为此,请在父构造函数中捕获订阅。

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);
        });
    }
}

<router-outlet></router-outlet>只是一个用于添加路由组件的占位符。不支持任何类型的绑定。

您可以创建自定义<router-outlet>,以允许您执行此操作,或者更常见的是,使用共享服务在父组件和路由组件之间进行通信。

有关更多详细信息,请参阅 https://angular.io/docs/ts/latest/cookbook/component-communication.html

更新

现在有一个事件允许获取添加的组件

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

它允许与componentAdded()中的组件进行通信(调用 getter、setter 和方法)

不过,共享服务是首选方式。

上面

给出的答案是正确和完整的。我只想为那些解决方案对他们不起作用的人补充一点,他们应该仅在父组件而不是子组件中将服务添加到提供程序,以确保您获得服务的单一实例,否则将创建两个服务实例。此回复的灵感来自上一个回复中@HeisenBerg的评论。

我与Antara Datta的回答相比略有改变。我创建了一个订阅者服务

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);
  }
}

每当我需要两个组件来共享一些信息时,我都会在订阅它的构造函数中注入此服务:

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

以及更新它的那个

constructor(protected router: Router, protected apiService: ApiService, protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
  {
    this.layoutOptions.next({showNavBar: false});
  }

我无法理解为什么路由器不转发"@Outputs"。

我最终调度了准系统DOM事件

// dom node needs to be a reference to a DOM node in your component instance
// preferably the root
dom.dispatchEvent(
      new CustomEvent('event', {
        detail: payload, // <- your payload here
        bubbles: true,
        composed: true,
      })
    );

您可以像任何其他 DOM 事件一样在 DOM 树上的任何位置捕获它

注意:您需要从接收端的{ detail: payload }中解压缩有效负载。

最新更新