Search code examples
angularangular2-template

DRY code in Angular2 templates?


I like the way you can easily bind properties, events etc. in angular2. You can put UI relevant code in your html and keep the component class pretty clean.

I have a snippet from a template i got, where i have a button to add the value of an input element, then clear the input field (to allow new input) and reset the focus in the element so you don't have to tab around a lot:

<div><input #newPlayer type="text">
<button type="button" 
(click)="addPlayer(newPlayer.value);newPlayer.value='';newPlayer.focus();">
ADD</button></div>

My component code is something like this:

public addPlayer(name: string) {
    if (!name.length) { return; };

    this.Players.push({ name: name});
}

This works great. The thing is, i figured that hitting the enter key in the input field should also behave like pressing the ADD button so my new html template looks like this:

<div><input #newPlayer type="text" 
(keyup.enter)="addPlayer(newPlayer.value);newPlayer.value='';newPlayer.focus();">
<button type="button" 
(click)="addPlayer(newPlayer.value);newPlayer.value='';newPlayer.focus();">
ADD</button></div>

Having to type the same list of commands for the extra event seems overkill, so i figured - what is the best pattern here? I was contemplating something like this:

<div><input #newPlayer type="text" 
(keyup.enter)="addPlayer(newPlayer)">
<button type="button" 
(click)="addPlayer(newPlayer)">
ADD</button></div>

Then change my component code to something like this:

public addPlayer(element: any) { // ElementRef?
    if (!element.value?.length) { return; };

    this.Players.push({ name: element.value});
    element.value = '';
    element.focus();
}

I'm not sure if this would even work, perhaps i need a reference to Renderer as well as ElementRef and this would confirm my suspicion that I'm not supposed to do this.

What would the best practice be?


Solution

  • Look at the below code, this might help you. I wonder if you need to learn how to use ElementRef to hold an input control:

     import {ElementRef,ViewChild} from '@angular/core';
    
     <input type="text" #newPlayer (keyup.enter)="addPlayer(newPlayer.value)" ... >
    

    In component:

    export class App{
    
        @ViewChild('newPlayer') input:ElementRef;
    
         addPlayer(){
      
           ...
    
         this.input.nativeElement.value=' ';
         this.input.nativeElement.focus();
    
         }
    
      }