无法解决路由器中使用的组件的输出事件中的承诺

时间:2017-10-09 16:59:59

标签: angular routing promise

我有一个组件,它意味着在另一个包含路由的组件中使用。该组件有一个输出事件,触发导航回父路径:

@Component({
  selector: 'hello',
  template: `
  <ng-content></ng-content>
  <button (click)="back($event)">Back</button>
  `
})
export class HelloComponent  {
  @Output() helloBack = new EventEmitter();

  constructor(private router: Router,
    private route: ActivatedRoute) {
  }

  back($event) {
    this.router.navigate(['./'], { relativeTo: this.route.parent })
      .then(() => {
        this.helloBack.emit($event);
      });
  }
}

接下来,我创建了在路径中使用的包装器组件:

@Component({
  template: `
  <hello (helloBack)="onBack()">
    <h1>Hello World!</h1>
  </hello>
  `
})
export class HelloRouteComponent {
  onBack() {
    console.log('back!!!');
  }
}

最后,我在路由模块中加载它:

RouterModule.forRoot([
  {
    path: 'hello',
    component: HelloRouteComponent
  }
])

当我转到/hello路线时,HelloRouteComponent加载正常。当我单击后退按钮时,它会导航到父路径,在成功导航后,它不会将任何内容记录到控制台。

为什么承诺没有解决?我错过了什么工作?

演示: https://stackblitz.com/edit/angular-rewax8?file=app%2Fapp.component.ts

2 个答案:

答案 0 :(得分:1)

我认为这是因为在router.navigate()被解析并且helloBack.emit()被调用时,绑定<hello (helloBack)="onBack()">不再存在,因为HelloComponent已经分离。< / p>

您可能希望使用声明Subject<T>字段的共享服务(@Output事件/ EventEmitter的自然替代品)。而是使用该主题。它有意义吗?

该服务可以如下所示:

@Injectable()
export class HelloContextService {

    private _helloBackSubject = new Subject<any>();
    $helloBack: Observable<any>;

    constructor() {
        this.$helloBack = this._helloBackSubject.asObservable();
    }

    emitHelloBack(payload: any): void {
        this._helloBackSubject.next(payload);
    }
}

您需要将其注入两个组件。然后HelloComponent可以调用this.emitHelloBack($event),其他组件可以订阅$helloBack可观察对象。

<强> HelloComponent

export class HelloComponent {

    constructor(private router: Router,
        private route: ActivatedRoute,
        private helloContextService: HelloContextService) {
    }

    back($event) {
        this.router.navigate(['./'], { relativeTo: this.route.parent })
            .then(() => {
                this.helloContextService.emitHelloBack($event);
            });
    }
}

另一个组成部分:

export class HelloRouteComponent  {
    constructor(private helloContextService: HelloContextService) {
        this.helloContextService
            .$helloBack
            .subscribe(payload => {
                // ...
            });
    }
}

答案 1 :(得分:0)

在您的应用程序中,您通过定义@Output类型变量来暴露事件发射器,并且您正在子组件中捕获它。所以看起来都很好。

我认为问题可能是this.router.navigate未被调用或onBack(event: EditEvent)您没有将参数传递给被调用函数。

@Component({
  selector: 'hello',
  template: `
  <ng-content></ng-content>
  <button (click)="back($event)">Back</button>
  `
})
export class HelloComponent  {
  @Output() helloBack = new EventEmitter();

  constructor(private router: Router,
    private route: ActivatedRoute) {
  }

  back($event) {
    this.helloBack.emit({status: 'gone back'});
    this.router.navigate(['./'], { relativeTo: this.route.parent })
      .then(() => {
        this.helloBack.emit($event);

      });
  }
}

将参数添加到onBack方法

@Component({
  template: `
  <hello (helloBack)="onBack()">
    <h1>Hello World!</h1>
  </hello>
  `
})
export class HelloRouteComponent {

  onBack(event: EditEvent) {
    console.log('back!!!');
  }
}
Finally, I load this in the routing module:

RouterModule.forRoot([
  {
    path: 'hello',
    component: HelloRouteComponent
  }
])

我认为一点点调试都可以解决您的问题。