10月メモ・リンク集
これは何か
- 10月に調べたことのメモ
- 基本形式は、「参考URLとそれに関するメモとコメント」
ngrx関連
ngrxとフォーム
- FormControl Freaks: Redux Edition - Daniel Figueiredo Caetano & Renee Vrantsidis - YouTube
- Reduxを使ったフォームの構築
- Template-driven Formsを利用
- ngrxでも考えは一緒
- validはデータとして持つのではなく、selectorで
- formcontrol-freaks/chapter.md at master · renvrant/formcontrol-freaks · GitHub
- スライド版
- Reduxを使ったフォームの構築
Introducing @ngrx/entity – @ngrx – Medium
- 新パッケージ
entity
に関して - platform/docs/entity at master · ngrx/platform · GitHub
状態のリセット
- angular - How to reset all states of ngrx/store? - Stack Overflow
- 各 feature moduleで
metaReducers
を利用してリセット(初期値)に戻す方法
// foo.module.ts ... StoreModule.forFeature( 'foo', fromCalendar.reducers, { metaReducers: [fromFoo.resetReducer] } ), ... // reducers/index.ts export function resetReducer(reducer: ActionReducer<FooState, reset.Actions>) { return function (state, action) { if (action.type === RESET) { return reducer(undefined, action); } else { return reducer(state, action); } }; }
How to share state between reducers best practice · Issue #159 · ngrx/example-app · GitHub
ActionReducerMap
とcombineReducers
- Beyond combineReducers · Redux
- Reduxにおけるreducer分割とcombineReducersについて - Qiita
Rx関連
unsubscribe
- RxJS: Don’t Unsubscribe – Ben Lesh – Medium
- Unsubscribe処理を必要以上に実行しないですむようなRxの書き方について
takeUntil
,takeWhile
など
- Angular/RxJs When should I unsubscribe from
Subscription
- Stack Overflow- Angularのコンポーネント内で作成したsubscriptionをどのようにunsubscribeするか
ngOnDestroy
,Subject
,takeUntil
を効果的に利用する
その他
- Observable.throw()が返すオブジェクトの型はErrorObservable - ryotah’s blog
- 「テキスト入力 -> 自動で検索開始」を実現するためのRx使い方 - ryotah’s blog
- Http - Observable completed function not firing · Issue #7865 · angular/angular · GitHub
- completeはエラー時には実行されない
- finallyを利用
Angular関連
view操作
- angular4 forms - Load Dynamic templates within a single component using Angular 4 - Stack Overflow
- 前月から引き続き
- templateを動的に外部から読み込んで表示させる #angular
- サンプル
- javascript - How to use Angular structural directive with multiple inputs - Stack Overflow
- Structural Directiveで複数のInput渡し方
<div *permissionIf="permissions;except:'Read'"></div>
- 最終的には以下のようになる
<template [permissionIf]="permissions" [permissionIfExcept]="'Read'">...
- 最終的には以下のようになる
- 動的に、対象要素の内部にコンポーネントを追加する #angualr · GitHub
- 「host要素の次に配置」ではなく、内部に追加したい場合は
renderer.appendChild
を使う - Using Renderer2 in Angular
- 「host要素の次に配置」ではなく、内部に追加したい場合は
ngOnInit() { const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SpinnerComponent); const componentRef = componentFactory.create(this.viewContainer.injector); this.renderer.appendChild( this.viewContainer.element.nativeElement, componentRef.location.nativeElement ); }
- RouterLinkActiveとそれをtemplate variableとして利用したときに #angular · GitHub
exportAs
の重要性- 上手く使えば簡単でシンプルなコードを提供できるようになる
フォーム
export class ChildComponent implements OnInit { ... @ViewChild("model") ngModel: NgModel; ngOnInit() { this.parentForm.addControl(this.ngModel); // <== add this this.parentForm.valueChanges.subscribe(changes => { console.log(JSON.stringify(changes)); }); } }
その他
null vs undefined
- null - JavaScript | MDN
- APIにおいては、通常はオブジェクトが返されるところで、関連したオブジェクトがない場合に
null
がよく渡されます。
- APIにおいては、通常はオブジェクトが返されるところで、関連したオブジェクトがない場合に
null
vs.undefined
in TypeScript land – BASARAT – MediumDon’t initialize optional sub properties
は確かに
TypeScript
- Revised Revised 型の国のTypeScript | Revised Revised TypeScript in Definitelyland](http://typescript.ninja/typescript-in-definitelyland/)
スニペット
Bootstrap4, デスクトップファースト
// Media of at most the maximum breakpoint width. No query for the largest breakpoint. // Makes the @content apply to the given breakpoint and narrower. @mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) { $max: breakpoint-max($name, $breakpoints); @if $max { @media (max-width: $max) { @content; } } @else { @content; } }
Htmlの<base href>
を取得
// <base href="/ja/"> const bases = document.getElementsByTagName('base'); if (bases.length > 0) { const baseHref = bases[0].href; // -> 'https://foo.com/ja/' }
Bugsnag
import { ErrorHandler, Injectable } from '@angular/core'; import { environment } from '../../environments/environment'; @Injectable() export class GlobalErrorHandler implements ErrorHandler { constructor() { Bugsnag.releaseStage = environment.stage; } handleError(error) { Bugsnag.notifyException(error); throw error; } }
ローダーのオンオフ、簡易版
function disable() { const elm: HTMLElement | null = document.getElementById('blocker'); if (elm) { elm.classList.add('active'); } } function enable() { const elm: HTMLElement | null = document.getElementById('blocker'); if (elm) { elm.classList.remove('active'); } }
Clickメモ
Array.apply(null, document.querySelectorAll('input[type=radio][value="3"]')).forEach(elm => elm.click());
Observable.throw()が返すオブジェクトの型はErrorObservable
import { Observable } from 'rxjs/Observable'; import { ErrorObservable } from 'rxjs/Observable/ErrorObservable'; // ... handleError(err): Observable<any>| ErrorObservable { if (/* 何か */) { return Observable.of('ok'); } else { return Observable.throw(err); } }
「テキスト入力 -> 自動で検索開始」を実現するためのRx使い方
- example-app/book.ts at ee0f331bf808525e003efa264b5065964c7f942b · ngrx/example-app · GitHub
- 元ネタ(NgRx4のサンプルアプリより)
シュミレート用サンプルコード
テキスト入力の代わりに、画面クリックで一連の流れが確認できる簡易版コードです。 ブラウザのコンソールで実行させれば、動作確認できます。
(http://reactivex.io/rxjs/などで実行してみてください。)
const sub = new Rx.BehaviorSubject(); const http = () => Rx.Observable.of('{ data }').delay(500); document.addEventListener('click', (e) => { sub.next(e); }); sub.debounceTime(1000) .distinctUntilChanged() .switchMap(() => { console.log('start http'); const next$ = sub.skip(1); return http().takeUntil(next$); }) .subscribe(val => console.log('get', val));
説明
.debounceTime
- 入力中に送信されないようにする
.distinctUntilChanged
- 前回と同じ値を送信しないようにする
.switchMap
- 未完了のhttp通信があった場合、無視する
.takeUntil(next$)
- debounceTimeで遅延させている間にhttp通信が完了する場合があるので、何かしらの入力変更があったらhttp通信を無視できるようにする
9月リンク集
- これは何か
- NgRx, アプリケーションの状態管理
- Rx関連
- Angular関連
- angular - @HostBinding and @HostListener: what do they do and what are they for? - Stack Overflow
- コンポーネントを動的に表示
- Change Detectionについて
- 私がMVCフレームワークをもはや使わない理由
- Running Protractor tests on Webdriver 2.47.1 gets - Error: Server terminated early with status 1 · Issue #2638 · angular/protractor · GitHub
- RouteReuseStrategy
- テスト
これは何か
- 9月に調べたことのメモ。基本形式は、「参考URLとそれに関するメモとコメント」。
- Angular関連がほとんど。
NgRx, アプリケーションの状態管理
A Comprehensive Introduction to @ngrx/store - Companion to Egghead.io Series
- 単純化したngrxの実装をしながら、Rxの機能、Reduxの考えかた、Rxによる実装方法がわかる
- Action -> Reducer -> Stateの流れ、Storeの実装方法、Reducerの合成、ミドルウェアなど
BehaviorSubject
,scan
,let
,distinctUntilChanged
,combineLatest
,withLatestFrom
など- Storeからデータを所得する方法、Store(State)のデータと表示用のデータをどう分けて管理するか #ngrx #angular · GitHub
- 個別のselectで取得, combineLatestでまとめる, projection functionを抽出して別ファイルor関数をつくる
// combine multiple state slices Observable.combineLatest( store.select('people'), store.select('events'), (people, events) => { // projection here })
Using NgRx 4 to Manage State in Angular Applications
- NgRxを使った状態管理について
- アプリケーションのStateを以下6種類に分けて考える
- Server state
- Persistent state
- The URL and router state
- Client state
- Transient client state
- Local UI state
- Using NgRx 4 to Manage State in Angular Applicationsのメモ #angular #rx #ngrx #redux · GitHub
- 日本語メモ
NgRx: Patterns and Techniques – nrwl
- アクションを3種類に分ける
- コマンド、ドキュメント、イベント
- エフェクト
- アクションの決定、アクションの変形、サイドエフェクト
- Reducerがやらないこと全てをおこなう
- NgRx: Patterns and Techniquesのメモ #angular #ngrx #redux #rx · GitHub
- 日本語メモ
platform/README.md at master · ngrx/platform · GitHub
- From Inactive to Reactive with ngrx Brandon Roberts & Mike Ryan - YouTube
- この動画 -> 公式のExampleアプリという順でみると理解しやすい
- https://github.com/ngrx/platform/blob/master/docs/store/README.md
- StoreからStateにアクセス
- StoreはStateのObservableでありActionのObserver
- Actionを受け取り、Stateを返す
- Reducer
export interface ActionReducer<T, V extends Action = Action> { (state: T | undefined, action: V): T; }
- https://github.com/ngrx/platform/blob/master/docs/effects/README.md
- Controlling Effects
- (メモ)
- Controlling Effects
- https://github.com/ngrx/platform/blob/master/docs/router-store/README.md
- どのタイミングでアクションをDispatchしているのか
- https://github.com/ngrx/platform/blob/0528d2ddea5a0a772d7130f7296984e82369961a/modules/router-store/src/router_store_module.ts#L176
(<any>this.router).hooks.beforePreactivation
- https://github.com/ngrx/platform/blob/0528d2ddea5a0a772d7130f7296984e82369961a/modules/router-store/src/router_store_module.ts#L216
this.router.events.subscribe
を利用- こっちは想像通り
- https://github.com/ngrx/platform/blob/0528d2ddea5a0a772d7130f7296984e82369961a/modules/router-store/src/router_store_module.ts#L176
- どのタイミングでアクションをDispatchしているのか
Rx関連
Rxのオペレータメモ #rx · GitHub
- 自分用のメモ
mergeMapとswitchMap
- RxJSのconcatMap, mergeMap, switchMapの違いを理解する(中級者向け) - Qiita
- rxjs - SwitchMap vs MergeMap in the #ngrx example - Stack Overflow
with the switchMap you can cancel the previous network request if it's running?
- 配列を返すことも可能
RxJS を学ぼう #2 – よく使う ( と思う ) オペレータ15選 – NET BIZ DIV. TECH BLOG
Angular関連
angular - @HostBinding and @HostListener: what do they do and what are they for? - Stack Overflow
- @HostBindingと@HostListenerのシンプルな利用例
コンポーネントを動的に表示
- Dynamically add components to the DOM with Angular – Frontend Weekly – Medium
-
@ViewChild('dynamic', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef
read
の存在知らなかった
-
- NgComponentOutlet
- 別の方法
- 表示するだけならこっちの方がシンプルに実装できる
- NgTemplateOutletもある
- angular - What are projectable nodes in angular2 - Stack Overflow
createComponent
の引数であるprojectableNodes
について
- angular4 forms - Load Dynamic templates within a single component using Angular 4 - Stack Overflow
- まだしっかりみてない
ng-template
を取得するためにGetTemplateDirectiveというDirectiveをつくる
Change Detectionについて
- 日本語訳:Angular 2 Change Detection Explained - Qiita
- わかりやすい。ありがたい
- イベント、XHR、タイマー
- Change And Its Detection In JavaScript Frameworks
- Angularに限らない話
markForCheck
とdetectChanges
の違いはわかるがどっちを使うべきかの説明がまだしっくりきていない- ルートからChange Detectionをはじめる
- Everything you need to know about change detection in Angular
Its content is based on the newest Angular version — 4.0.1. The way how change detection mechanism is implemented under the hood in this version is different from the earlier 2.4.1.
私がMVCフレームワークをもはや使わない理由
Running Protractor tests on Webdriver 2.47.1 gets - Error: Server terminated early with status 1 · Issue #2638 · angular/protractor · GitHub
- Macを買い換えたらE2Eのテストがこけてしまった
- 原因はJavaのバージョン
export JAVA_HOME="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home"
- 原因はJavaのバージョン
RouteReuseStrategy
- 実際にはこのような使い方をしていないがメモとして
/** * コンポーネントの再描画のルールを変更 * https://medium.com/@juliapassynkova/angular-2-component-reuse-strategy-9f3ddfab23f5 */ export class CustomRouteReuseStrategy implements RouteReuseStrategy { // copy from DefaultRouteReuseStrategy shouldDetach(route) { return false; } store(route, detachedTree) { } shouldAttach(route) { return false; } retrieve(route) { return null; } // override shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { return this._shouldReuseRoute(future, curr) && this.isUnChanged(future, curr); } private _shouldReuseRoute(future, curr) { return future.routeConfig === curr.routeConfig; } /** * 追加ルール * 特定コンポーネントかつ、`key`が変更した時 */ private isUnChanged(future, curr) { const name = future.component && (<any>future.component).name; if (name === 'BarComponent') { if (future.paramMap.get('key') && curr.paramMap.get('key') && future.paramMap.get('key') !== curr.paramMap.get('key')) { return false; } } return true; } }
テスト
selenium - Debugging “Element is not clickable at point” error - Stack Overflow
Angular (4)で設定したLocale IDを取得
LOCALE_ID
を利用。
以下のようにAOTでコンパイルしていない場合、初期値のen-US
になります。
ng serve --aot --locale ja
import { Component, OnInit, LOCALE_ID, Injector } from '@angular/core'; export class FooComponent implements OnInit { constructor(private injector: Injector) { } ngOnInit() { const locale = this.injector.get(LOCALE_ID); // -> 'ja' } }
雑メモはGist (Lepton) に
プログラムに関する備忘録をこのブログに書いていましたが、それくらいの文章やコードならGistにあげればいいのかと思い始めました。
Leptonというアプリがあるのでしばらくそれを使ってみようかと思います。
Quiver、SnippetsLabなど他のアプリも試してみましたが、今のところLeponが自分の用途にはあってそうです。
- Lepton
- GIstのクライアントアプリ
- 無料
- Quiver
- SnippetsLab
以下ページも参考になりそうです。
AngularのTemplate Syntax
Angular - Template Syntaxを読んだメモです。
(v4.3.6対応)
- Binding一覧
- Operator一覧
- Built-in attribute directives
- Two-way
- *ngForのtrackByを使って描画対象かどうかを判断する
- Template reference variables ( #var )
- その他
Binding一覧
<!-- Property -->https://angular.io/guide/template-syntax <img [src]="heroImageUrl"> <hero-detail [hero]="currentHero"></hero-detail> <greeting message="hello"></greeting><!-- プロパティが文字列かつテンプレートに直接埋め込む場合 --> <!-- Attribute --> <tr><td [attr.colspan]="1 + 1">One-Two</td></tr> <!-- Class --> <div class="bad curly special" [class]="badCurly">Bad curly</div><!-- `badCurly`で上書きされる --> <div [class.special]="isSpecial">The class binding is special</div><!-- 特定のクラスのon/off --> <!-- Style --> <button [style.color]="isSpecial ? 'red': 'green'">Red</button> <button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button> <!-- Event --> <button (click)="onSave()">Save</button>
参考
- https://angular.io/guide/template-syntax#property-binding–property-
- https://angular.io/guide/template-syntax#attribute-class-and-style-bindings
- https://angular.io/guide/template-syntax#event-binding—event-
Operator一覧
<!-- Pipe --> <div>Title through uppercase pipe: {{title | uppercase}}</div> <!-- Safe navigation operator (`?.`) --> The null hero's name is {{nullHero?.name}} <!-- Non-null assertion operator (`!`)--> <div *ngIf="hero"> The hero's name is {{hero!.name}} </div>
参考
- https://angular.io/guide/template-syntax#template-expression-operators
- http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator
Built-in attribute directives
ngClass
- 複数のクラスを管理する場合に有効
<div [ngClass]="currentClasses"></div>
- https://angular.io/guide/template-syntax#ngClass
ngStyle
- 複数のインラインスタイルを管理する場合に有効
<div [ngStyle]="currentStyles"></div>
- https://angular.io/guide/template-syntax#ngStyle
ngModel
Two-way
export class SizerComponent { @Input() size: number | string; @Output() sizeChange = new EventEmitter<number>(); ... resize(delta: number) { this.sizeChange.emit(this.size); } }
<!-- 以下コードは同じ結果になる --> <my-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></my-sizer> <my-sizer [(size)]="fontSizePx"></my-sizer>
*ngForのtrackBy
を使って描画対象かどうかを判断する
Template reference variables ( #var )
- https://angular.io/guide/template-syntax#template-reference-variables–var-
A template reference variable is often a reference to a DOM element within a template. It can also be a reference to an Angular component or directive or a web component.
その他
DOM propertyとは
- https://angular.io/guide/template-syntax#html-attribute-vs-dom-property
Attributes are defined by HTML. Properties are defined by the DOM (Document Object Model). * > Attributes initialize DOM properties and then they are done. Property values can change; attribute values can’t.
- HTML attribute と DOM property - Please Sleep
Template expressions/statementsで利用できないJS構文
- expressions
- statements
- https://angular.io/guide/template-syntax#template-statements
The template statement parser differs from the template expression parser and specifically supports both basic assignment (
=
) and chaining expressions (with;
or,
).
- https://angular.io/guide/template-syntax#template-statements
Template expressionsのガイドライン
- https://angular.io/guide/template-syntax#expression-guidelines
No visible side effects
Quick execution
Simplicity
Idempotence (冪等性)