2017-10-09 34 views
1

我有一个组件可用于包装路由的另一个组件。该组件触发导航回父路由的输出事件:无法解析在路由器中使用的组件中的输出事件中的承诺

@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

回答

1

我相信这是因为当router.navigate()得到解决,并helloBack.emit()被调用时,绑定<hello (helloBack)="onBack()">不会再因为HelloComponent已经脱离存在。

您可能想要使用声明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 => { 
       // ... 
      }); 
    } 
} 
+0

感谢您的快速响应。你能证明这项服务的工作原理吗? – elclanrs

+0

看看代码。 :) –

+0

我看到...不确定这将适用于我的用例,因为路由组件是由使用我的组件的用户创建的,并且我无法控制该组件,并且我不希望用户拥有注入服务等等。 – elclanrs

0

在您的应用程序可以通过定义@Output类型变量暴露事件发射器,你都不禁儿童compoenent。所以一切看起来不错。

我想问题可能是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 
    } 
]) 

我想调试的点点能够解决您的问题。