Search code examples
angulartemplatestypescriptcomponentsgeneric-programming

Angular 2 duplicate component in template reference another element


Simplified I have a component that can be used multiple times within any template. How would I get my component click-me to pair with the input element below it so when the event (click in this case) is fired it will apply (change the input type to hidden in this case) to that input. Obviously the approach is important here not the hide!

What can I add to pair them keeping the duplicate component generic and autonomous?

enter image description here

import {Component} from 'angular2/core';

@Component({
    selector: 'click-me',
    template: `<button (click)="onClickMe()">Hide A Friend Input</button>`
})

COMPONENT

export class DuplicateComponent {
    onClickMe() {
        alert("try change type");
        this.type = "hidden";
    }
}

TEMPLATE

<div>
  <click-me></click-me>
  <input type="input" value="friend 2 to hide" id="clickme1">
</div>

<div>
  <click-me></click-me>
  <input type="input" value="friend 2 to hide" id="clickme2">
</div>

Click here for Plunker


Solution

  • What i would do is

    1. Define an output event in the DuplicateComponent component
    2. Fire the output event whithin the onClickMe() method
    3. Define via template variables a specific name for each occurence of DuplicateComponent in the template of the ContainerComponent (i.e. the component which contains the instances of DuplicateComponent)
    4. Listen to the newly created event in each occurence of the DuplicateComponent with a method which passes the specific DuplicateComponent instance which has fired the event
    5. Do what is required with the DuplicateComponent instance within the method attached as listener of the newly created event

    It may sound complex, but I think the code is pretty simple (see working plunkr)

    DuplicateComponent

    import {Component, Output, EventEmitter} from 'angular2/core';
    @Component({
        selector: 'click-me',
        template: `<button (click)="onClickMe()">Hide A Friend Input</button>`
    })
    export class DuplicateComponent {
      @Output() haveBeenClicked = new EventEmitter<any>();
        onClickMe() {
            this.haveBeenClicked.next();
            this.type = "hidden";
        }
    }
    

    AppComponent template

    <div>
      <click-me (haveBeenClicked)="doStuff(two)"></click-me>
      <input type="input" value="friend 2 to hide" id="clickme2" #two>
    </div>
    

    AppComponent

    @Component({
        selector: 'my-app',
        templateUrl: 'app/app.component.html',
        directives: [DuplicateComponent]
    })
    export class AppComponent {
      constructor AppComponent {}
    
      doStuff(inputElement) {
        console.log(inputElement);
      }
    }