【问题标题】:Angular 4 execute function from another componentAngular 4从另一个组件执行功能
【发布时间】:2017-12-31 09:39:51
【问题描述】:

我正在使用 Angular4 构建一个 web 应用程序,并且我正在尝试创建一个按钮来调用其他组件上的函数。

我在这里阅读了其他类似的问题,但他们有这样一种情况,即组件是子组件或兄弟组件,并在 html 上声明,例如:

<parent-component>
    <child-component></child-component>
    <sibling-component></sibling-component>
</parent-component>

但是,我正在处理不同的场景,因为我的组件是通过 routing 调用的,我无法使其工作。

基本上我在页面上有一个header,其中包含一些执行功能的控件,但是这些功能需要触发/更改通过路由加载的其他组件上的数据。

例如,我有路由/store 来显示商店列表,我在此页面上还有一个抽屉,我想在用户单击标题上的按钮时显示它,这就是问题所在,因为我无法将事件从HeaderComponent 传播到StoreComponent

这些是我的文件:

header.component.ts

@Component({
    selector: 'header',
    templateUrl: `
        <section class="container">
            <button (click)="clickFilter()">Open filter</button>
        </section>
    `
})

export class HeaderComponent {
    @Output() onFilter: EventEmitter = new EventEmitter();

    clickFilter():void {
        this.onFilter.emit('Register click');
    }
}

store.component.ts

@Component({
    templateUrl: 'store.html'
})

export class StoreComponent {
    onFilterClick(event) {
        console.log('Fire onFilterClick: ', event);
    }
}

// store.html
<article class="card" (onFilter)="onFilterClick($event)">
    Test
</article>

但这不起作用。

另外,我实际上不需要调用函数,我可以只传递一个布尔值,例如,绑定到 StoreComponent 上的属性,然后切换 html 文件中的 div。

【问题讨论】:

  • 这些组件在应用程序中的排列方式并不完全清楚。 stackoverflow.com/help/mcve 会有所帮助。不处于父子关系的组件可以通过公共父级或通过父级注入器上的服务进行通信。如果不能通过父母进行交流……算一算。

标签: angular


【解决方案1】:

我没有时间测试它,但类似的解决方案对我有用。为您的需要创建的代码。

创建这样的服务

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class MessageService {
    private _listners = new Subject<any>();

    listen(): Observable<any> {
       return this._listners.asObservable();
    }

    filter(filterBy: string) {
       this._listners.next(filterBy);
    }

}

然后像这样在你的标题组件中实现

// header.component.ts
@Component({
    selector: 'header',
    templateUrl: `
        <section class="container">
            <button (click)="clickFilter()">Open filter</button>
        </section>
    `
 })

export class HeaderComponent {
     @Output() onFilter: EventEmitter = new EventEmitter();

     constructor(private _messageService: MessageService){}
     clickFilter():void {
         // this.onFilter.emit('Register click');
         this._messageService.filter('Register click');
     }
 }

然后像这样在您的商店组件中使用

@Component({
    selector: 'store',
    template: `<article class="card">
                 Test
              </article>`
})

export class StoreComponent {
    constructor(private _messageService: MessageService){
        this._messageService.listen().subscribe((m:any) => {
            console.log(m);
            this.onFilterClick(m);
        })
    }

    onFilterClick(event) {
        console.log('Fire onFilterClick: ', event);
    }
 }

这个概念是你可以在服务中使用 observable 并订阅你想要的组件(store.component),并且可以像我在 header.component 中所做的那样从应用程序的任何地方发送事件

希望对你有帮助

【讨论】:

  • 不错!完美运行。另外,我认为使用服务会更好,因为我可以将所有共享功能放在一个地方,而不是到处都是。
  • StoreComponent 中存在小错字(订阅 -> 订阅),其余部分对我来说非常完美。谢谢
  • header组件中EventEmitter有什么用?
  • 查看标题组件中的 clickFilter() 发出事件的行已注释,因此您可以从标题组件中删除 EventEmitter。我写了它显示问题的解决方案
  • 如何在 store.component 中取消订阅?
【解决方案2】:

我有类似的情况,但不想为此提供服务。我设法像回调一样传递它。应该是这样的:

header.component.ts

@Component({
selector: 'header',
templateUrl: `
    <section class="container">
        <button (click)="myFunction()">Open filter</button>
    </section>
`})
export class HeaderComponent {
   @Input() myFunction: Function;
}

然后只是调用它传递函数和参数

// store.html
<header [myFunction]="functionOnStore"></header>

并且只是在 store 组件上正常声明 functionOnStore

【讨论】:

  • 似乎这会将函数传递给组件,而不是调用它?
  • 是的。它将传递函数但也会调用/执行它。这是 JS 的魔法!!!
猜你喜欢
  • 2018-09-12
  • 1970-01-01
  • 2018-06-14
  • 2019-01-05
  • 2015-10-19
  • 2018-06-12
  • 1970-01-01
  • 2021-11-04
  • 2018-02-20
相关资源
最近更新 更多