LoginSignup
0
1

More than 3 years have passed since last update.

Angular基礎メモ

Last updated at Posted at 2020-10-29

Angularの基礎的なことを備忘録として残しておきます。

環境

Angular: 9.1.2
Angular CLI: 9.1.12
Node: 12.18.3
OS: win32 x64

参考

公式:Angular入門 チュートリアル
https://angular.jp/start

Angular入門 未経験から1ヶ月でサービス作れるようにする
https://qiita.com/seteen/items/43908e33e08a39612a07

Angular Tutorial - 21 - Fetch Data Using HTTP(httpClient.getの使い方)
https://www.youtube.com/watch?v=LmIsbzt-S_E&list=PLC3y8-rFHvwhBRAgFinJR8KHIrCdTkZcZ&index=21

テンプレート構文

・HTML上で書ける基本のテンプレート構文
- *ngFor
- *ngIf
- 補間 {{ }} EL式みたいなの。
- プロパティバインディング [ ] 
- イベントバインディング ( )

補間

補間構文 {{ }} は
TypeScriptで宣言した変数の値をHTMLでテキスト表示する。 

app.componet.html
<h1>{{ title }}</h1> // test-angularが表示される。
app.componet.ts
export class AppComponent { 
  title = 'test-angular'; 
}

プロパティバインディング

typescript → html方向のバインド
公式の説明:プロパティバインディングは、値をコンポーネントのプロパティから 対象の要素のプロパティへと、単方向に流します。
私の理解:[ ]で囲ったDOM要素に対してTypeScriptで定義した要素を入力する。 

[プロパティ名] = "変数名"

app.component.html
<a [href]="url">Googleへ</a>
app.componet.ts
export class AppComponent {
  url = 'https://www.google.com';
}

上記はHTMLのa要素のhrefプロパティにapp.componetのurlプロパティをバインドしている。

ngFor

1、tsファイルで配列を定義。

app.component.ts
import { Component } from '@angular/core'; 
@Component({ 
  selector: 'app-root', 
  templateUrl: './app.component.html', 
  styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
  title = 'test-angular'; 
  url = 'https://www.google.com'; 
  i: number[] = [0,1,2]; 
}

2,htmlファイルでngFor

app.component.html
<h1>{{ title }}</h1> 
<a [href]="url">Googleへ</a> 
<div *ngFor="let item of i"> 
  <p>{{item}}</p> 
</div> 

*ngFor="let aaa of bbb"はbbb配列の要素をaaaに1個ずつ入れて取り出す。
Javaの拡張for文のような感じ。

補足、添え字番号の取得など
<li *ngFor="let item of i; let j = index; let f = first>
jに添え字番号、fに最初の要素かどうかの boolean が入る。

ngIf

1、tsファイルで配列を定義。

app.component.ts
import { Component } from '@angular/core'; 
@Component({ 
  selector: 'app-root', 
  templateUrl: './app.component.html', 
  styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
  i: number[] = [0,1,2,null]; //追加
}

2、htmlファイルでngIf

app.component.html
//i[3]がnullならこのdivを表示。nullでないならi3を表示。
<div *ngIf="i[3] === null; else i3"> 
  i[3]はありません。 
</div> 

// nullでない時はこちらが表示される。ng-template要素。
<ng-template #i3> 
  {{i[3]}} 
</ng-template> 

イベントバインディング

html ⇒ typescript方向のバインド。

1、 ボタンのclickイベントを、alertOn()メソッドに紐付けます。
イベントバインディングは(click)のように、イベントを囲むカッコ ( ) を使用します。

app.component.html
<button (click)="alertOn()">アラート</button>

2、alertOn()メソッドをtsファイルに追加。

app.component.ts
import { Component } from '@angular/core'; 
@Component({ 
  selector: 'app-root', 
  templateUrl: './app.component.html', 
  styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
 // alertOn()メソッドの追加。
  alertOn(): void { 
    alert('イベントバインディング'); 
  } 
}

〇主なイベント一覧
click クリック
dbclick ダブルクリック
mousedown マウスボタンを押した時
mouseup マウスボタンを離した時
mouseenter マウスポインターが要素に入った時
mousemove マウスポインターが要素内を移動した時
mouseleave マウスポインターが要素から離れた時
focus 要素にフォーカスした時
blur 要素からフォーカスが外れた時
keydown キーを押した時
keypress キーを押し続けている時
keyup キーを離した時
input 入力内容が変更された時
select テキストが選択された時
reset リセット時
submit サブミット時

双方向バインディング

外部(ブラウザ)からの入力と内部(スクリプト)からの入力の双方向で値を更新する仕組み。
ブラウザ⇔変数⇔TypeScript

1、HTMLで[(ngModel)]要素を作る。

app.component.html
<input type="text" name="name" [(ngModel)]="message"> 
<div> 
  メッセージ:{{ message }} 
</div>

2、TypeScriptでmessage変数を定義。

app.component.ts
import { Component } from '@angular/core'; 
@Component({ 
  selector: 'app-root', 
  templateUrl: './app.component.html', 
  styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
  message: string;  //ここを追加。
}

Component

一連のUI機能を再利用できる。
Android開発でいうところのレイアウトみたいなもの。(リニアレイアウトの中にテーブルレイアウトが入ってたりイメージビューが入ってたり)

以下、Angular公式の引用。

コンポーネントは3つの要素で構成されています。

TypeScript:コンポーネントクラス では、データと機能を処理します。前のセクションでは、コンポーネントクラス内の製品データとshare()メソッドはそれぞれデータと機能を処理しました。

HTML:HTMLテンプレート では、UIを決定します。 前のセクションでは、商品リストのHTMLテンプレートを変更して、各商品の名前、説明、および"Share"ボタンを表示しました。

CSS:コンポーネント固有スタイル では、ルック・アンド・フィールを定義します。 商品リストにはスタイルは定義されていませんが、 ここにはコンポーネントCSSが存在します。

コンポーネントの生成

angular CLIで

ng generate component hero-detail(コンポーネント名)

ng generate componentは4つのファイルを生成する。
CSS・HTML・TypeScript・テストファイル

ルーティング

ルーティングとはURLに応じてコンテンツの部分を動的に表示させる仕組みです。
ページ遷移等。

ルーティング基礎1

aaaComponentをルーティングで表示。
1、app-routing.module.tsでAaaComponentをインポート。
  さらにpathを追加。

app-routing.module.ts
import { NgModule } from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router'; 

import { AaaComponent } from './test/aaa/aaa.component'; // ここを追加

const routes: Routes = [ 

// ここを追加。http://localhost:4200/aaaに接続したら、AaaComponentが動作しますよということ。
  { path: 'aaa', component: AaaComponent }
]; 
@NgModule({ 
  imports: [RouterModule.forRoot(routes)], 
  exports: [RouterModule] 
}) 
export class AppRoutingModule { }

2、app.module.tsがapp-routing.module.tsを参照するように定義する。

app.module.ts
import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core'; 
import { AppRoutingModule } from './app-routing.module'; 
import { AppComponent } from './app.component';  //ここを追加。 
@NgModule({ 
  declarations: [ 
    AppComponent, 
    ProductListComponent, 
    ProductDetailComponent, 
    BbbComponent 
  ], 
  imports: [ 
    BrowserModule, 
    AppRoutingModule  // ここを追加。
  ], 
  providers: [], 
  bootstrap: [AppComponent] 
}) 
export class AppModule { }

3、app.component.htmlに下記を追加。
これでhttp://localhost:4200/aaaに接続するとaaa.component.htmlの中身が表示されるようになる。

app.component.html
<router-outlet></router-outlet>

ルーティング基礎2

・リダイレクト
1、app-routing.module.tsでpathを追加する。
ttp://localhost:4200/aaaにリダイレクトされる。

app-routing.module.ts
import { NgModule } from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router'; 
const routes: Routes = [ 
{ path: 'aaa', component: AaaComponent }, 
{ path: '', redirectTo: '/aaa', pathMatch: 'prefix' } //ここを追加するだけ。
]; 
@NgModule({ 
  imports: [RouterModule.forRoot(routes)], 
  exports: [RouterModule] 
}) 
export class AppRoutingModule { }

pathMatch: 'prefix'の意味
・prefix : URLが path の値で始まる場合 (今回の場合は、>http://localhost:4200/ で始まるすべてのURL。事前に定義されている /aaa を除く) にリダイレクトします。
・full: の場合はURLが path と完全に一致した場合(今回の場合 >http://localhost:4200/ ) にリダイレクトします。

ルーティング基礎3

・ページ遷移
aaa.component.html ⇔bbb.component.htmlでの遷移

1、app-routing.module.tsでpathを追加する

app-routing.module.ts
import { NgModule } from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router'; 
import { AaaComponent } from './test/aaa/aaa.component'; 
import { BbbComponent } from './test/bbb/bbb.component';  //追加
const routes: Routes = [ 
  { path: 'aaa', component: AaaComponent }, 
  { path: 'bbb', component: BbbComponent },  // 追加
  { path: '', redirectTo: '/aaa', pathMatch: 'prefix' }, 
]; 
@NgModule({ 
  imports: [RouterModule.forRoot(routes)], 
  exports: [RouterModule] 
}) 
export class AppRoutingModule { }

2、app.module.tsにインポート。

app.module.ts
import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core'; 
import { AppRoutingModule } from './app-routing.module'; 
import { AppComponent } from './app.component'; 
import { AaaComponent } from './test/aaa/aaa.component'; 
import { BbbComponent } from './test/bbb/bbb.component';  //追加。多分自動で追加される。
@NgModule({ 
  declarations: [ 
    AppComponent, 
    AaaComponent, 
    BbbComponent //追加。多分自動で追加される。
  ], 
  imports: [ 
    BrowserModule, 
    AppRoutingModule 
  ], 
  providers: [], 
  bootstrap: [AppComponent] 
}) 
export class AppModule { }

3、aaa.component.html にリンクをはる。

aaa.component.html
<p>aaa works!</p> 
//http://localhost:4200/bbbに遷移。
<button [routerLink]="['/bbb']"> 
  bbbへ 
</button>

4、bbb.component.html にリンクをはる。

bbb.component.html
<p>bbb works!</p> 
//http://localhost:4200/aaaに遷移。
<button [routerLink]="['/aaa']"> 
  aaaへ 
</button>

Service

Angular公式から引用。

サービスはAngularアプリケーションの不可欠な部分です。 Angularでは、
サービスはAngularの 依存性の注入システム を使用してアプリケーションの任意の部分で使用できるクラスのインスタンスです。
サービスは、アプリケーションの各部分の間でデータを共有する場所です。
オンラインストアの場合、カートサービスはカートデータとメソッドを保存する場所です。
逆にコンポーネントクラスは呼び出すだけ。

・なぜサービスが必要なのか?
Angular公式から引用。

コンポーネント内では直接データの取得や保存を行うべきではありません。もちろん、故意に仮のデータを渡してもいけません。
コンポーネントはデータの受け渡しに集中し、その他の処理はサービスクラスへ委譲するべきです。

・サービスの生成
ng generate service hero(サービス名)

・サービスの使用方法
参考:https://angular.jp/start/start-data

cart.service.ts
import { Injectable } from '@angular/core'; 
@Injectable({ 
  providedIn: 'root' 
}) 
export class CartService { 
items = []; 
  addToCart(product) { 
    this.items.push(product); 
  }
}

サービスを使用したいtsファイルにインポート

productdetails.component.ts
import { CartService } from '../cart.service';

サービスを使用したいtsファイルのコンストラクタに注入

productdetails.component.ts
export class ProductDetailsComponent implements OnInit { 
  constructor( 
    private route: ActivatedRoute, 
    private cartService: CartService //依存性の注入
  ) { } 
}

サービスを使用したいtsファイルでメソッドを呼び出し。

productdetails.component.ts
export class ProductDetailsComponent implements OnInit { 
    this.cartService.addToCart(product);
}

GETリクエストの送り方

1、app.module.tsでインポート

app.module.ts
import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core'; 
import { AppRoutingModule } from './app-routing.module'; 
import { AppComponent } from './app.component'; 
import { HttpClientModule } from '@angular/common/http'
import { HttpClientModule } from '@angular/common/http';// ここを追加。

@NgModule({
  declarations: [
    AppComponent
  ],
imports: [ 
    BrowserModule, 
    AppRoutingModule, 
    HttpClientModule // ここを追加。
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

1-2、jsonファイルを用意する
/assets/data/employees.json

employees.json
[
  {"id": 1, "name": "Andrew", "age": 30},
  {"id": 2, "name": "Brandon", "age": 25},
  {"id": 3, "name": "Christina", "age": 26},
  {"id": 4, "name": "Elena", "age": 28},
  {"id": 5, "name": "Felicia", "age": 25}
]

2、サービスクラスGETリクエストを送る。
http.getメソッドを呼ぶメソッドを作る。返り値型はObservable<?>

Employee.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { IEmployee } from './employee.model';
@Injectable({
  providedIn: 'root'
})
export class EmployeeService {

  private url: string = '/assets/data/employees.json';

  constructor(private http: HttpClient) { }

  // getの後の<IEmployee[]>はキャストらしい。
  getEmployees(): Observable<IEmployee[]> {
    return this. http.get<IEmployee[]>(this.url);
  }
}

3、戻り値用のモデルクラスを作る

employee.model.ts
export interface IEmployee {
  id: number,
  name: string,
  age: number
}

4、http.getメソッドを呼ぶメソッドを呼ぶメソッドを作るw

app.component.ts
import { Component, OnInit } from '@angular/core'; 
import { EmployeeService } from './employee.service'; 
@Component({ 
  selector: 'app-root', 
  templateUrl: './app.component.html', 
  styleUrls: ['./app.component.css'] 
}) 
export class AppComponent implements OnInit{ 
  public employees = []; //返り値はここに入る 

  // 依存性の注入。EmployeeServiceの注入。 
  constructor(private employeeService: EmployeeService) {} 

  ngOnInit() { 
    // getEmployeesを呼び出し。返り値をemployees配列に代入。 
    this.employeeService.getEmployees() 
      .subscribe(data => this.employees = data); 
  } 
}

5、HTMLで表示

app.component.html
<h2>Employee List</h2>
    <ul *ngFor="let employee of employees">
      <li>{{employee.name}}</li>
    </ul>
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1