Monday 21 September 2020

Angular components

Now I have a particular way of organizing my projects, it's not the best way because there is no best way; you have to come up with something that works for you and then force your team to follow your conventions because you are the smartest person on your team just like everyone else... 

anyway, I like to put my root component into a root folder, I like to put my child components into a folder called components but i like to put my layout components into a layout folder. You maybe wondering why, well its just the way my brain works, doesn't mean that yours works this way; so let's start with creating a header.component and putting into the layouts folder.

First hit ctrl+c to stop your live dev server, then the angler command to generate a component is

ng generate component <Path/component.name> or ng g c <Path/component.name>

so in our case type in the following

ng generate component layout/header

and we should end up with the following 

next lets open our header.componenet.ts file

what we need to make a note of is the selector, if you recall this is how we will put our component into our html, now open up our app.component.html file and add our component selector which we highlighted above for our header component.

<app-header></app-header>
<div>
  hello world!!!
</div>

now lets run our application and check it out ng server

ok so that's great, next let's open up our header.component.html file again and modify it 

from this

<p>header works!</p>

to this

<header>
  <h1>Tic Tac Toe</h1>
</header>

and navigate back to our application and bam!!! no refresh No restart our changes are automatically refreshed.

now let's create a simple grid for our game, first lets stop our applicaiton using ctrl+c in the terminal window, then next let's create a new component called grid under a components folder

ng generate component components/grid

and voila we have our grid component, so lets start with creating our ui, open up the Grid.componenet.html file and lets just do something simple, nine buttons each one of which will represent one of our tic tac to cells.

<div class="container">
  <div class="grid">
    <!-- first row -->
    <button class="cell" (click)="onMark($event, 0)"><span id="cell00" class="content"></span></button>
    <button class="cell" (click)="onMark($event, 1)"><span id="cell10" class="content"></span></button>
    <button class="cell" (click)="onMark($event, 2)"><span id="cell20" class="content"></span></button>

    <!-- second row -->
    <button class="cell" (click)="onMark($event, 3)"><span id="cell01" class="content"></span></button>
    <button class="cell" (click)="onMark($event, 4)"><span id="cell11" class="content"></span></button>
    <button class="cell" (click)="onMark($event, 5)"><span id="cell21" class="content"></span></button>

    <!-- third row -->
    <button class="cell" (click)="onMark($event, 6)"><span id="cell02" class="content"></span></button>
    <button class="cell" (click)="onMark($event, 7)"><span id="cell12" class="content"></span></button>
    <button class="cell" (click)="onMark($event, 8)"><span id="cell22" class="content"></span></button>
  </div>
</div> 

we are going to style them in you guessed it the style sheet, the interesting thing to notice is this (click) attribute, this is an angular event, it binds the click event of this control to an onMark method in our grid.component.ts file; so that seems like a natural place to look next.

all we did here is created a onMark(evetn: MouseEvnet, cellId:number): void method

import { ComponentOnInit } from '@angular/core';

@Component({
  selector: 'app-grid',
  templateUrl: './grid.component.html',
  styleUrls: ['./grid.component.scss']
})
export class GridComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  onMark(eventMouseEvent, cellIdnumber): void {
    alert(cellId)
  }
}

we added a simple alert(cellId) body to our onMark method just to ensure that it works, so lets execute it and see.

sure enough if we click one of the little butons we get an alert with its corresponding cellId. finally lets make this look somewhat like a tic tac toe board. for that lets navigate to our grid.componenet.scss file and paste in the following

.container {
  display:flex;  
  justify-contentcenter;

  .grid{
    flex-wrapwrap;
    width:70vh;
 
    >.cell{
      width33.33%;
      padding-top33.3%;
      positionrelative;
      
      .content{
        positionabsolute;
        top:0;
        bottom:0;
        left:0;
        right:0;
        font-size2em;
        displayflex;
        flex-directioncolumn;
        justify-contentcenter;
      }
    }
  }
}

The above SCSS creates a grid out of our buttons; now if we take a look at our grid again

it's starting to look rather respectable, lets just quickly open up our app.component.html file and remove the div with hello world. 

I think that is enough for this post, next we'll great a service to communicate with our api