0

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

0

3 Answers 3

2

Make use of Template references #click1 and #click2 so that you can take control of your component.

    <div>
      <click-me #click1></click-me>
      <input type="input" value="friend 2 to hide" id="clickme1" [hidden] = "click1.type">
    </div>

    <div>
      <click-me #click2></click-me>
      <input type="input" value="friend 2 to hide" id="clickme2" [hidden] = "click2.type">
    </div>
Sign up to request clarification or add additional context in comments.

4 Comments

@PaulThomas In your plunker here, use [type] instead of just type, since you are dealing with angular.
<input [type]="#input1.showType" value="friend 2 to hide"> Nope throws parse error
@PaulThomas <input [type]="input1.showType" value="friend 2 to hide"> do not use # while using it.
2

Using Translusion

Demonstration

I think the best way to make this component is to transclude whatever you want inside the duplicate component.

Then inside the duplicate component you can store the transcluded content inside a span tag so the styling will be preserved. Then add a click handler that toggles the hiding of the span tag.

Note that you can use this not just with input elements but other components simply by wrapping them in the duplicate component.

// app.component.html

// app.component.html
<click-me>
  <input type="input" value="friend 1 to hide" id="clickme2">
</click-me>

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

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

// duplicate.component.ts
import {Component} from 'angular2/core';

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

export class DuplicateComponent {
    hidden = false;

    onClickMe() {
        this.hidden = !this.hidden;
    }
}

5 Comments

I like the approach of swapping in the code for which I have given a vote. However the point was really to get a handle on the non-duplicated element to be handled by the duplicate component.
Ah I understand. In that case using template references is probably best. I'll see if I can give you a good solution without duplicating anything else written here.
@PaulThomas I added another solution where you pass in the template variable for you target. This should be more flexible than the last solution. Is it what you're looking for?
Yes the new one is pretty much what Amit Chigadani provided with template references. So thumbs up as well.
You're right that's the same thing. I'll remove the second solution to reflect that.
0

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);
  }
}

5 Comments

Plunker not working, or at least it's not making the input field hidden?
Yes, it just prints the input element on the console. Once you have an hold on the Input element within the code, then you can do whatever you want.
I am just confused because yes you get a handle but the function onClickMe() last line does "this.type = "hidden"; However this doesnt seem to do anything, I would have expected it to hide the input?
The line "this.type = "hidden"; is there because it was there in your first plunkr and I did neither remove it nor thought that hiding the input element was important for you. In any case here is the plunkr that works and hides the input element.
Perfect, I see you're passing the reference through the function haveBeenClicked, I missed this before. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.