完成したもの
動画
ソースコード
GitHub
( https://github.com/RyoMiyashita/ng-click-input )
アプリケーションの概要
- macOS Sierra: 10.12.6
- npm: 5.7.1
- Angular CLI: 6.0.8
- Node: 8.9.4
- Angular: 6.0.7(4以上で動く??)
- rxjs: 6.2.1
- typescript: 2.7.2
- webpack: 4.8.3
解説
div要素でnameを表示しておく。divがダブルクリックされたら関数を動かしてフラグを反転する。
フラグを用いて表示していたdivを非表示にし、代わりにinputを表示させる。
inputのblurを使ってフォーカスが外れたタイミングで再度フラグを反転させることによってinputが非表示になり、divが表示される。
テンプレート
<div>
<input #testInput type="text" [(ngModel)]="name" *ngIf="isOpen" (blur)="change()">
<div *ngIf="!isOpen" (dblclick)="change()">{{name}}</div>
</div>
nameを表示するdiv要素にはダブルクリックを検知するために(dblclick)
をつけておく。また、isOpen
フラグを用いて表示、非表示を切り替えるために*ngIf
をつける。
ダブルクリックされた後に表示するinputにはコンポーネントから呼び出せるように#testInputと名前をつけておく。inputの入力を変数に格納するためにngModelは入出力どちらもできるようにしておく。isOpen
のフラグを用いて表示、非表示を切り替えれるように*ngIf
を用いる。blurのイベント検知を取るために(blur)
をつける。
クラス
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public isOpen = false;
public name = 'cipher';
constructor(
) { }
@ViewChild('testInput') // inputにfocusを当てる
set myInput(_input: ElementRef | undefined) {
if (_input !== undefined) {
_input.nativeElement.focus();
}
}
change() {
this.isOpen = !this.isOpen;
}
}
inputとdivの表示、非表示を切り替えるためのフラグをisOpen
、表示する要素をname
として変数を宣言する。@ViewChild
(@ViewChild Angular公式)を用いてinputにつけた名前を使ってDOM要素にアクセスする。seterを使うことによって常時監視することができる。非表示の際はundefined
になってしまうため、条件分岐しておく。ElementRef
のnativeElement
を用いてfocus
関数を動かしてフォーカスを当てている。
change
関数はフラグを反転させるための関数である。
最後に
今回はinputを一つだけでしたが、複数にする際は表示、非表示のフラグを変えてあげれば複数でも対応できるかと思います。