3

In the following example, I designate a local variable #input to multiple radio buttons. When clicking the <tr> I want to select the radio button inside.

And the following code works fine, but I don't understand why.

How can Angular2 "know" which input I'm refering to when ALL of them have the local variable#input?

HTML

  <tr *ngFor="let office of employee.offices" (click)="selectOffice(input)">
    <td class="select-office-radio">
      <input type="radio" name="office" #input />
    </td>
    <td>
      {{office.officeName}}
    </td>
  </tr>

JS

selectOffice(input) {
   input.checked = true;
}
3
  • shouldn't the JS be selectOffice(user) as opposed to selectUser(input)? Commented Jul 8, 2016 at 10:46
  • and I believe it's because each office has it's own mini-template and is unaware of the other mini-templates that have been created by the *ngFor which means that only one is triggered Commented Jul 8, 2016 at 10:51
  • updated. ok thanks for the info, do you know if this is documented somewhere? Commented Jul 8, 2016 at 10:54

2 Answers 2

5

As Bhushan said, ngFor is a structural directive so it's a shortcut for a template-based structure. In short, it can be desugared into the following in your template:

<template ngFor let-office [ngForOf]="employee.offices">
  <tr (click)="selectOffice(input)">
    (...)
  </tr>
</template>

The way to define local variable for templates is the following:

  • Add the prefix let-. For example, let-office will define a variable office.
  • If you don't define a value, the value of the $implicit entry in the template context will be used. In the case of ngFor, it's the current element in the iteration. Here: let-office.
  • You can also specify a value. For example, if you want to define a variable for the index in the loop: let-i="index". In the case, the variable i will contain the corresponding value.

Regarding variables define with the # prefix. They correspond to a DOM element if the element they apply on isn't a component. If it's a component, it corresponds to the component. For example, input in <input #input/> corresponds to an ElementRef and the DOM element can be accessed through its nativeElement property.

You can also specify a value for such variables. In this case, you can select a specific directive applied on the element. For example <input #ctrl="ngModel" [(ngModel)]="val"/>. The value corresponds to what is specified within the exportAs attribute in the directive declaration:

@Directive({
  selector: 'child-dir',
  exportAs: 'child'
})
class ChildDir {
}

@Component({
  selector: 'main',
  template: `<child-dir #c="child"></child-dir>`,
  directives: [ChildDir]
})
class MainComponent {
}
Sign up to request clarification or add additional context in comments.

Comments

1

*ngFor is a structural directive i.e. it modifies the DOM.

thus, for each record its creating its creating separate input element.

Also you are declaring #input as a local variable for input element thus #input refers to each input element separately.

if you want to access the value entered in text input, you can do following:

selectOffice(input.value)

because #input refers to html input element.

for more info, you can refer to :

Displaying Data using structural directives

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.