「Angular」の版間の差分
ナビゲーションに移動
検索に移動
| 1行目: | 1行目: | ||
| − | ==Angular== | + | ==[[Angular]]== |
[[TypeScript]] | [[Google Cloud Platform]] | [[Bootstrap]] | [[Flask]] | | [[TypeScript]] | [[Google Cloud Platform]] | [[Bootstrap]] | [[Flask]] | | ||
{{amazon|4774191302}} | {{amazon|4774191302}} | ||
| − | ==Angular CLI== | + | ==[[Angular]] CLI== |
===インストール=== | ===インストール=== | ||
| − | >npm install -g @angular/cli | + | >[[npm]] install -g @angular/cli |
===アプリケーションの生成=== | ===アプリケーションの生成=== | ||
| 10行目: | 10行目: | ||
===アプリケーションの実行=== | ===アプリケーションの実行=== | ||
> ng serve | > ng serve | ||
| − | ===Angular CLI の主なコマンド=== | + | ===[[Angular]] CLI の主なコマンド=== |
*https://github.com/angular/angular-cli/wiki | *https://github.com/angular/angular-cli/wiki | ||
{|class="wikitable" | {|class="wikitable" | ||
| 49行目: | 49行目: | ||
|ng set key=value | |ng set key=value | ||
|- | |- | ||
| − | |Angular CLIのバージョン | + | |[[Angular]] CLIのバージョン |
|ng version | |ng version | ||
|- | |- | ||
| 71行目: | 71行目: | ||
|- | |- | ||
|サービス | |サービス | ||
| − | |ng g | + | |ng g ser[[vi]]ce hoge |
|- | |- | ||
|ガード | |ガード | ||
| 88行目: | 88行目: | ||
==ngx-bootstrap== | ==ngx-bootstrap== | ||
*https://valor-software.com/ngx-bootstrap | *https://valor-software.com/ngx-bootstrap | ||
| − | * | + | *[[Bootstrap]]をAgularアプリケーションから利用 |
| − | ===Angular-CLIから利用=== | + | ===[[Angular]]-CLIから利用=== |
*https://github.com/valor-software/ngx-bootstrap/blob/development/docs/getting-started/ng-cli.md | *https://github.com/valor-software/ngx-bootstrap/blob/development/docs/getting-started/ng-cli.md | ||
=====インストール===== | =====インストール===== | ||
| − | npm install ngx-bootstrap bootstrap --save | + | [[npm]] install ngx-bootstrap bootstrap --save |
=====src/app/app.module.ts の編集===== | =====src/app/app.module.ts の編集===== | ||
import { AlertModule } from 'ngx-bootstrap'; | import { AlertModule } from 'ngx-bootstrap'; | ||
| 110行目: | 110行目: | ||
[[File:0167_bootstrap_alert.jpg]] | [[File:0167_bootstrap_alert.jpg]] | ||
| − | ==Angular Material== | + | ==[[Angular]] Material== |
*https://material.angular.io/ | *https://material.angular.io/ | ||
==非同期通信== | ==非同期通信== | ||
| 192行目: | 192行目: | ||
*/src/app/app-routing.module.ts を追加 | */src/app/app-routing.module.ts を追加 | ||
import { NgModule } from '@angular/core'; | import { NgModule } from '@angular/core'; | ||
| − | import { | + | import { [[R]]outes, [[R]]outerModule } from '@angular/router'; |
const routes: Routes = []; | const routes: Routes = []; | ||
| 198行目: | 198行目: | ||
@NgModule({ | @NgModule({ | ||
imports: [ | imports: [ | ||
| − | + | [[R]]outerModule.for[[R]]oot(routes), | |
], | ], | ||
exports: [RouterModule] | exports: [RouterModule] | ||
}) | }) | ||
| − | export class | + | export class App[[R]]outingModule { } |
*/src/app/app.module.ts | */src/app/app.module.ts | ||
| − | import { | + | import { App[[R]]outingModule } from './app-routing.module'; |
: | : | ||
@NgModule({ | @NgModule({ | ||
imports: [ | imports: [ | ||
BrowserModule, | BrowserModule, | ||
| − | + | App[[R]]outingModule, | |
], | ], | ||
providers: [], | providers: [], | ||
*/src/app/app.component.spec.ts | */src/app/app.component.spec.ts | ||
| − | import { | + | import { [[R]]outerTestingModule } from '@angular/router/testing'; |
: | : | ||
describe('AppComponent', () => { | describe('AppComponent', () => { | ||
| 219行目: | 219行目: | ||
TestBed.configureTestingModule({ | TestBed.configureTestingModule({ | ||
imports: [ | imports: [ | ||
| − | + | [[R]]outerTestingModule | |
], | ], | ||
declarations: [ | declarations: [ | ||
| 231行目: | 231行目: | ||
*app-routing.module.ts | *app-routing.module.ts | ||
import { NgModule } from '@angular/core'; | import { NgModule } from '@angular/core'; | ||
| − | import { | + | import { [[R]]outes, [[R]]outerModule } from '@angular/router'; |
import { AccountComponent } from './account/account.component' | import { AccountComponent } from './account/account.component' | ||
| 242行目: | 242行目: | ||
@NgModule({ | @NgModule({ | ||
imports: [ | imports: [ | ||
| − | + | [[R]]outerModule.for[[R]]oot(routes), | |
], | ], | ||
exports: [RouterModule] | exports: [RouterModule] | ||
}) | }) | ||
| − | export class | + | export class App[[R]]outingModule { } |
====利用==== | ====利用==== | ||
<a routerLink="/account">Account</a> | <a routerLink="/account">Account</a> | ||
| 297行目: | 297行目: | ||
*モジュールにサービスを登録する。 | *モジュールにサービスを登録する。 | ||
*コンポーネントにも登録できる。この場合コンポーネントと子コンポーネントのみで利用できる。 | *コンポーネントにも登録できる。この場合コンポーネントと子コンポーネントのみで利用できる。 | ||
| − | import { | + | import { HogeSer[[vi]]ce } from './hoge.ser[[vi]]ce'; |
@NgModule({ | @NgModule({ | ||
| 305行目: | 305行目: | ||
}) | }) | ||
===依存性注入=== | ===依存性注入=== | ||
| − | *方法を宣言するのは、@NgModule/@Component デコレータの | + | *方法を宣言するのは、@NgModule/@Component デコレータの pro[[vi]]dersパラメータ |
| − | * | + | *サービスを提供するためのPro[[vi]]derオブジェクトを登録する |
| − | ===== | + | =====Pro[[vi]]derであることの条件は以下のプロパティを持つこと===== |
{|class="wikitable" | {|class="wikitable" | ||
!プロパティ | !プロパティ | ||
!内容 | !内容 | ||
|- | |- | ||
| − | | | + | |pro[[vi]]de |
|サービスを注入する際に利用するDIトークン | |サービスを注入する際に利用するDIトークン | ||
|- | |- | ||
| 319行目: | 319行目: | ||
|- | |- | ||
|multi | |multi | ||
| − | | | + | |同一のDIトークンに対して複数のPro[[vi]]derを追加するか |
|- | |- | ||
|} | |} | ||
| 345行目: | 345行目: | ||
*常に新たなインスタンスを生成する | *常に新たなインスタンスを生成する | ||
providers: [ | providers: [ | ||
| − | { | + | { pro[[vi]]de: HogeSer[[vi]]ce, useClass: HogeSer[[vi]]ce } |
] | ] | ||
=====useValue===== | =====useValue===== | ||
| 351行目: | 351行目: | ||
*クラスのインスタンスを渡す | *クラスのインスタンスを渡す | ||
providers: [ | providers: [ | ||
| − | { | + | { pro[[vi]]de: HogeSer[[vi]]ce, useVlaue: new HogeSer[[vi]]ce() } |
] | ] | ||
=====useExisting===== | =====useExisting===== | ||
*トークンのエイリアスを生成 | *トークンのエイリアスを生成 | ||
providers: [ | providers: [ | ||
| − | { | + | { pro[[vi]]de: HogeSer[[vi]]ce, useClass: HogeSer[[vi]]ce }、 |
| − | { | + | { pro[[vi]]de: HogeAliasSer[[vi]]ce, useExisting: HogeSer[[vi]]ce }、 |
] | ] | ||
<blockquote>互換性維持など、別のトークンから同一インスタンスを取得したい場合などに利用</blockquote> | <blockquote>互換性維持など、別のトークンから同一インスタンスを取得したい場合などに利用</blockquote> | ||
| 363行目: | 363行目: | ||
*ファクトリー関数経由でインスタンスを生成 | *ファクトリー関数経由でインスタンスを生成 | ||
providers: [ | providers: [ | ||
| − | { | + | { pro[[vi]]de: HogeSer[[vi]]ce, useFactory: () => { |
| − | let | + | let ser[[vi]]ce = new HogeSer[[vi]]ce(); |
| − | + | ser[[vi]]ce.foo = "bar"; | |
| − | return | + | return ser[[vi]]ce; |
} | } | ||
} | } | ||
| 374行目: | 374行目: | ||
===Http=== | ===Http=== | ||
*https://angular.io/guide/http | *https://angular.io/guide/http | ||
| − | == | + | ==[[R]]xJs== |
===コンポーネントからサービスのデータを購読する=== | ===コンポーネントからサービスのデータを購読する=== | ||
| − | *https://angular.io/guide/component-interaction#!#bidirectional- | + | *https://angular.io/guide/component-interaction#!#bidirectional-ser[[vi]]ce |
| − | ===== | + | =====Ser[[vi]]ce===== |
import { Subject } from 'rxjs/subject'; | import { Subject } from 'rxjs/subject'; | ||
import { User } from './user'; | import { User } from './user'; | ||
@Injectable() | @Injectable() | ||
| − | export class | + | export class AccountSer[[vi]]ce { |
private userChangeAnnouncedSource = new Subject<User>(); | private userChangeAnnouncedSource = new Subject<User>(); | ||
userChangeAnnounced$ = this.userChangeAnnouncedSource.asObservable(); | userChangeAnnounced$ = this.userChangeAnnouncedSource.asObservable(); | ||
| 398行目: | 398行目: | ||
ngOnInit() { | ngOnInit() { | ||
| − | this.subscription = this. | + | this.subscription = this.accountSer[[vi]]ce.userChangeAnnounced$.subscribe((user:User) => { |
this.user = user; | this.user = user; | ||
}); | }); | ||
| 409行目: | 409行目: | ||
==UI== | ==UI== | ||
| − | ===Angular Material=== | + | ===[[Angular]] Material=== |
*https://material.angular.io/ | *https://material.angular.io/ | ||
====レスポンシブレイアウト==== | ====レスポンシブレイアウト==== | ||
| − | *https://material.angular.io/cdk/layout/ | + | *https://material.angular.io/cdk/layout/over[[vi]]ew |
==テスト== | ==テスト== | ||
===ユニットテスト=== | ===ユニットテスト=== | ||
| 418行目: | 418行目: | ||
*https://karma-runner.github.io/2.0/index.html | *https://karma-runner.github.io/2.0/index.html | ||
*karma.conf.js | *karma.conf.js | ||
| − | ==Tips== | + | ==[[Tips]]== |
===機能=== | ===機能=== | ||
====Chrome拡張機能==== | ====Chrome拡張機能==== | ||
| 426行目: | 426行目: | ||
*https://developers.facebook.com/docs/javascript | *https://developers.facebook.com/docs/javascript | ||
| − | ====Hello.js | + | ====Hello.js 認証をまとめる[[JavaScript]]ライブラリ==== |
*http://adodson.com/hello.js/#scope | *http://adodson.com/hello.js/#scope | ||
===文法=== | ===文法=== | ||
| − | ==== | + | ====[[Java]]scriptのグローバルオブジェクトを利用==== |
declare const hoge; | declare const hoge; | ||
===コード=== | ===コード=== | ||
====コードからルーティング==== | ====コードからルーティング==== | ||
| − | import { | + | import { [[R]]outer } from '@angular/router'; |
: | : | ||
| − | constructor(private router: | + | constructor(private router: [[R]]outer) {} |
: | : | ||
this.router.navigate(['/hoge']) | this.router.navigate(['/hoge']) | ||
| − | ==== | + | ====CS[[R]]F==== |
*https://angular.io/api/common/http/HttpClientXsrfModule | *https://angular.io/api/common/http/HttpClientXsrfModule | ||
*https://angular.io/guide/http | *https://angular.io/guide/http | ||
2020年2月16日 (日) 04:21時点における版
目次
Angular
TypeScript | Google Cloud Platform | Bootstrap | Flask |
Angular CLI
インストール
>npm install -g @angular/cli
アプリケーションの生成
> ng new myapp
アプリケーションの実行
> ng serve
Angular CLI の主なコマンド
| 概要 | コマンド |
|---|---|
| appアプリを生成 | ng new app |
| ひな形の生成 | ng generate ... |
| ビルドして起動 | ng serve |
| ビルド | ng build |
| ユニットテスト | ng test |
| E2Eテスト | mg e2e |
| i118nメッセージを抽出 | ng xi18n |
| 指定されたキーワードで検索 | ng doc keyword |
| TSLintによるコードチェック | ng lint |
| 現在の設定を取得 | ng get key |
| 指定されたキー/値を設定 | ng set key=value |
| Angular CLIのバージョン | ng version |
ng generate サブコマンド
| 要素 | コマンド |
|---|---|
| モジュール | ng g moduole hoge |
| コンポーネント | ng g component hoge |
| ディレクティブ | ng g directive hoge |
| パイプ | ng g pipe hoge |
| サービス | ng g service hoge |
| ガード | ng g guard hoge |
| クラス | ng g class hoge |
| インターフェース | ng g interface hoge |
| 列挙 | ng g enum hoge |
ngx-bootstrap
- https://valor-software.com/ngx-bootstrap
- BootstrapをAgularアプリケーションから利用
Angular-CLIから利用
インストール
npm install ngx-bootstrap bootstrap --save
src/app/app.module.ts の編集
import { AlertModule } from 'ngx-bootstrap';
:
@NgModule({
:
imports: [AlertModule.forRoot(), ... ],
:
})
.angular-cli.json に以下を追加
"styles": [ "../node_modules/bootstrap/dist/css/bootstrap.min.css", "styles.css" ],
src/app/app.component.html に以下を追加
<alert type="success">hello</alert>
Angular Material
非同期通信
app.module.ts
import { HttpModule } from '@angular/http';
:
@NgModule({
:
imports: [
:
HttpModule,
],
:
})
データバインディング
構文
| データ方向 | 種類 | 記法 |
|---|---|---|
| コンポーネント -> ビュー | 補間 | {{...}} |
| コンポーネント -> ビュー | プロパティ/属性バインディング | [property]='value' |
| ビュー -> コンポーネント | イベントバインディング | (event)='handler' |
| コンポーネント <-> ビュー | 双方向バインディング | [(target)]='value' |
テンプレート参照変数
- 変数名
- (change)="0"は、イベントトリガーで値を更新するため必要
<input #txtHoge type="text" (change)="0"/> <div>テンプレート:TxtHoge.value</div>
双方向バインディング
- import と @NgModule の imports に FormModuleを追加
ルートモジュール(app.modules.ts)
import { FormsModule } from '@angular/forms';
:
@NgModule({
:
imports: [
BrowserModule,
FormsModule,
:
ビュー
- input/textarea/selectなどフォーム要素をバインドするには、ngModel を利用する
- このためには、name属性の指定が必須
- ngModelを[(ngModel)]とする
<select name="selAcion" [(ngModel)]="selectedAction">
<option *ngFor="let item of testActions" value="テンプレート:Item" >テンプレート:Item</option>
</select>
コンポーネント
export class AccountComponent implements OnInit {
testActions: string[] = [,'login','logout','check'];
selectedAction: string = ;
入力値の加工
- 上記は、プロパティバインディング、イベントバインディングを組み合わせて、双方向を実現している。
- データバインディング時に値を加工する場合、[(ngModel)] を [ngModel]と(ngModelChagen) に分解
- $eventは入力値そのものを表す
<input name="hoge" type="text" [ngModel] = "hogeName" (ngModelChange) = "hogeName=$event.toUpperCase()" />
ルーティング
適用
プロジェクト作成
> ng new app --routing
--routing オプションを付与せずにプロジェクトを作成した場合
- /src/app/app-routing.module.ts を追加
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [
RouterModule.forRoot(routes),
],
exports: [RouterModule]
})
export class AppRoutingModule { }
- /src/app/app.module.ts
import { AppRoutingModule } from './app-routing.module';
:
@NgModule({
imports: [
BrowserModule,
AppRoutingModule,
],
providers: [],
- /src/app/app.component.spec.ts
import { RouterTestingModule } from '@angular/router/testing';
:
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
コンポーネント作成
> ng g component account --routing
ルーティング定義
- app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AccountComponent } from './account/account.component'
const routes: Routes = [
{
path: 'account', component: AccountComponent
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes),
],
exports: [RouterModule]
})
export class AppRoutingModule { }
利用
<a routerLink="/account">Account</a> <router-outlet></router-outlet>
コンポーネント
ライフサイクル
| ライフサイクル | 内容 |
|---|---|
| コンポーネント生成 | |
| コンストラクター | |
| ngOnChanges | @Input経由で入力値が設定/再設定された |
| ngOnInit | 入力値(@Inputp)が処理された後、コンポーネントの初期化時(最初のngOnChangesメソッドの後で一度だけ) |
| ngDoCheck | 状態の変更を検出したとき |
| ngAfterContentInit | 外部コンテンツを初期化した時(最初のngDoCheckメソッドの後で一度だけ) |
| ngAfterContentChecked | 外部コンテンツの変更をチェックした時 |
| ngAfterViewInit | 現在のコンポーネントと子コンポーネントのビューを生成した時(最初のngAfterContentCheckedメソッドの後で一度だけ) |
| ngAfterViewChecked | 現在のコンポーネントと子コンポーネントのビューが変更された時 |
| ngOnDestroyed | コンポーネントが破棄される時 |
| コンポーネント破棄 |
サービス
- サービスクラスであることの条件は、@Injectable デコレータを付与することのみ。
- @Injectable デコレータは、コンポーネントに対してサービスを引き渡せることを意味する。
登録
- モジュールにサービスを登録する。
- コンポーネントにも登録できる。この場合コンポーネントと子コンポーネントのみで利用できる。
import { HogeService } from './hoge.service';
@NgModule({
:
providers: [HogeService],
:
})
依存性注入
Providerであることの条件は以下のプロパティを持つこと
| プロパティ | 内容 |
|---|---|
| provide | サービスを注入する際に利用するDIトークン |
| useXxxxx | サービスの生成方法 例 userClass: XXXX と指定するとクラス XXXX を常にnew でインスタンス化する |
| multi | 同一のDIトークンに対して複数のProviderを追加するか |
useXxxx
| プロパティ | 内容 |
|---|---|
| useClass | 指定されたクラスを注入のたびにインスタンス化 |
| useValue | 指定されたオブジェクトを常に引き渡す(同じ値になる) |
| useExisting | 指定されたトークンのエイリアスを生成 |
| useFactory | 指定されたファクトリー関数で注入の際にオブジェクトを生成 |
useClass
- 常に新たなインスタンスを生成する
providers: [
{ provide: HogeService, useClass: HogeService }
]
useValue
- 常に同じオブジェクトを注入する
- クラスのインスタンスを渡す
providers: [
{ provide: HogeService, useVlaue: new HogeService() }
]
useExisting
- トークンのエイリアスを生成
providers: [
{ provide: HogeService, useClass: HogeService }、
{ provide: HogeAliasService, useExisting: HogeService }、
]
<blockquote>互換性維持など、別のトークンから同一インスタンスを取得したい場合などに利用</blockquote>
useFactory
- ファクトリー関数経由でインスタンスを生成
providers: [
{ provide: HogeService, useFactory: () => {
let service = new HogeService();
service.foo = "bar";
return service;
}
}
]
Modules
Http
RxJs
コンポーネントからサービスのデータを購読する
Service
import { Subject } from 'rxjs/subject';
import { User } from './user';
@Injectable()
export class AccountService {
private userChangeAnnouncedSource = new Subject<User>();
userChangeAnnounced$ = this.userChangeAnnouncedSource.asObservable();
:
announceUserChange(user: User) {
this.userChangeAnnouncedSource.next(user);
}
:
Component
import { Subscription } from 'rxjs/Subscription';
export class AccountComponent implements OnInit, OnDestroy {
user: User;
subscription: Subscription
ngOnInit() {
this.subscription = this.accountService.userChangeAnnounced$.subscribe((user:User) => {
this.user = user;
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
:
UI
Angular Material
レスポンシブレイアウト
テスト
ユニットテスト
Karma
- https://karma-runner.github.io/2.0/index.html
- karma.conf.js
Tips
機能
Chrome拡張機能
Facebook SDK
Hello.js 認証をまとめるJavaScriptライブラリ
文法
Javascriptのグローバルオブジェクトを利用
declare const hoge;
コード
コードからルーティング
import { Router } from '@angular/router';
:
constructor(private router: Router) {}
:
this.router.navigate(['/hoge'])
CSRF
- https://angular.io/api/common/http/HttpClientXsrfModule
- https://angular.io/guide/http
- Angular + HttpClientXsrfModule + Flask で CSRF
参照
© 2006 矢木浩人

