Angular 5 Component input function that takes parameters

有些话、适合烂在心里 提交于 2020-07-04 11:35:48

问题


In an Angular 2+ component, how do I pass in a callback function that takes parameters? My initial assumption was something like

<app-example [onComplete]="doThing('someParam')"></app-example>

And sometimes I won't need any parameters, like this:

<app-example [onComplete]="doSomeThingElse()"></app-example>

And then in the component I have

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent {
  @Input() public onComplete: () => void;

  //run `this.onComplete()` somewhere as needed
}

But, what ends up happening is that the doThing('someParam') or doSomeThingElse() is immediately called without any interaction.

How am I supposed to pass callback functions in to a component to be called later?


EDIT:

The actual problem I am trying to solve here is to be able to run any passed in function at a later time. This is for a confirmation component that will ask the user "are you sure you want to continue?" and then if they press the "Yes I'm sure" button, the passed in function will run.


回答1:


Here's an example of the @Output syntax @toskv was looking for, Angular pass callback function to child component as @Input

So for your example,

<app-example 
  (onComplete)="doThing()" 
  [completedParam]="'someParam'"></app-example>
@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent {
  @Output() public onComplete: EventEmitter<any> = new EventEmitter();
  @Input() completedParam;

  runOnComplete(): void {
    this.onComplete.emit(this.completedParam);
  }
}

Does not feel as good as [onComplete]="doThing.bind(this, 'someParam')".




回答2:


The said solution will work only if you have a method that needs to invoke without taking action on the component itself. However, in my case, I need to execute an observable method inside of the app-example component and wait for the response to do some action inside of that component.

If anyone has the same issue. Here is the solution for it.

  1. create an interface.

    export interface Delegate<T> {
      (...args: any[]): T;
    }
    
  2. On your angular component, create a @Input variable

    @Component({
        selector: 'app-example',
        templateUrl: './example.component.html',
    })
    export class AppExampleComponent {
      @Input() executeWhen: Delegate<Observable<any>>;
    
      runOnComplete(): void {
        this.executeWhen().subscribe(() => // do some action);
      }
    }
    



回答3:


Template:

<app-example [someParams]="someParamsObject"
             (complete)="onComplete($event)" >
</app-example>

Component:

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent {
  @Input()
  someParams: YourParamsType;

  @Output()
  complete:EventEmitter<any> = new EventEmitter<any>();

  //run `this.complete(this.someParams)` somewhere as needed and 
  //pack in some params if you need
}

In your calling, parent component you need a function named onComplete that receives parameter of type any in this case (that comes from @Output being defined as EventEmitter<any>). If you need, you can also have event parameters of any particular type you like EventEmitter<YourParticularType>.




回答4:


You can have a private method in your component:

private doThingFactory(param) {
  return () => this.doThing(param);
}

and then use it like that:

<app-example [onComplete]="doThingFactory('someParam')"></app-example>


来源:https://stackoverflow.com/questions/48012662/angular-5-component-input-function-that-takes-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!