2

Good afternoon guys, i have the following structure:

parent.html

<child-component>
<ng-template let-dataSource="dataSource" let-displayedColumns="dc">
  <mat-table class="cruds-table" [dataSource]="dataSource" matSort fusePerfectScrollbar>

      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef mat-sort-header>Nome</mat-header-cell>
        <mat-cell *matCellDef="let crud">
          <p class="text-truncate" (click)="clica()">{{crud.name}}</p>
        </mat-cell>
      </ng-container>
 [...]</ng-template>
</child-component>

child.html

<ng-container *ngTemplateOutlet="contentTable;context:{dataSource: dataSource, dc: displayedColumns}"></ng-container>

child.ts

clica(){
    alert('clicked');
}

when I click on it, the function is triggered on the parent component, i know i can use View to get the child component and use as child.clica(), but i have many functions and i would prefer to bind all the events inside of this container to the child component.

Is there any way to do this?

Sorry if it's confusing, it's complicated to explain. Thanks!

Bill P
  • 3,622
  • 10
  • 20
  • 32
Matheus
  • 23
  • 1
  • 5

3 Answers3

1

If you are clear with javascript functionality and Angular, Here is the trickier way to go :

constructor(app:AppComponent){ //<-- get the ref of the parent component
    app['clic'] = this.clic; //<-- declare function and bind our function 
    this.name = 'myself';
}

clic(){
    alert('clicked');
}

ngOnDestroy() {
    delete this.app['clic']; // <-- get rid of the function from parent component, when we are done
}

WORKING DEMO

NOTE : I have also explored the solution just for fun, but it's really cool

You can load parent component in child in many ways DO READ.

Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
0

You can set up an EventEmitter on your child component and bind to that event in your parent component.

inside child.ts

@Output
clickEvent: EventEmitter<any> = new EventEmitter();
...
click() {
    this.clickEvent.emit(eventArgs);
}

parent.html

<child-component (clickEvent)="someFuncOnParent()"></child-component>

parent.ts

someFuncOnParent(event) { 
    //event args can be passed to parent here 
}

If you're trying to go the other direction you can use the @Input on the child with an EventEmitter, like so.

child.ts

@Input
clica: EventEmitter<any> = new EventEmitter();

ngOnInit() {
    this.clica.subscribe(() => alert('clicked'));
}

parent.html

<child-component [clica]="parentClickEvent">
<ng-template>
  <button (click)="parentClick()">
    Click Me!
  </button>
</ng-template>
<child-component>

parent.ts

parentClickEvent: EventEmitter<any> = new EventEmitter();

parentClick() {
    this.parentClickEvent.next();
}

https://stackblitz.com/edit/angular-oyxkwb

Lazy Coder
  • 1,157
  • 1
  • 8
  • 18
  • Yes, my problem actually is the opposite. the function is being already called on the parent component. In my example, clicking to fire the trigger i got the message: "ERROR TypeError: _co.clica is not a function" Once, it was defined within the child only. – Matheus Aug 09 '19 at 18:20
  • Can you throw up an example on stackblitz? – Lazy Coder Aug 09 '19 at 18:26
  • Pasted forked stackblitz with second example implemented – Lazy Coder Aug 09 '19 at 18:52
  • Thanks!! I got your point but my idea is to create a kind of framework, so i don't wanna obligate the user to implement all the functions on the parent component, u understand? But anyway, i'm so glad for ur quick response and help! – Matheus Aug 13 '19 at 16:30
0

The less tricker way to go:

child:

<ng-container *ngTemplateOutlet="contentTable;context:{dataSource: dataSource, dc: displayedColumns, clica: clica}"></ng-container>

parent:

<ng-template let-dataSource="dataSource" let-displayedColumns="dc" let-clica="clica">
J. Reynolds
  • 151
  • 3
  • 14