Angular:カスタムしたdirectiveを動的にタグに埋め込みたい
この質問はhttps://teratail.com/questions/142007にも投稿しています。
質問に回答がつかなかった為、こちらにも投稿させてもらいました。質問内容は下記です。
Angular6で、複数の画面で共通のdirectiveを使おうと思っています。
複数のプログラマーがテンプレートに個々にdirectiveを埋め込むと抜け漏れが発生するので、
name="corp_name"のinputタグの場合、必ず"HanToZen"というdirectiveを埋め込む様に
ngOnInitで実装したいのですが、うまくいきません。
もしかすると、setAttributeした後にテンプレートをコンパイルしなおさないといけないのかと思い、現在はその方向で調べています。
どなたかご教授頂けるととても助かります。どうぞよろしくお願いします。
※directiveで呼んでいるconvertHAN2ZENは受け取った文字列の半角文字を全角に変換するだけの関数です。
directiveが有効になる方法が分かれば、処理の内容は何でもいいので省略させて頂きました。
試したコードは下記です。
directive-test.component.ts
import { Component, OnInit, ElementRef, Renderer2 } from '@angular/core';
@Component({
selector: 'app-directive-test',
templateUrl: './directive-test.component.html',
styleUrls: ['./directive-test.component.css']
})
export class DirectiveTestComponent implements OnInit {
element: HTMLElement;
constructor(private el: ElementRef,private renderer: Renderer2) {
this.element = el.nativeElement;
}
ngOnInit() {
// 単純にHTMLelementにZenToHanをsetしてみると、DOMは期待通りになるのですがdirectiveが動きませんでした
var input = this.element.getElementsByTagName("input");
for (var i = 0; i < input.length; i++) {
if ( input[i].getAttribute("name") === "corp_name") {
input[i].setAttribute("HanToZen","");
}
}
// Renderer2でcreateも試してみましたが、HTMLelementにsetAttributeした時と結果は同じでした
var rendInput = this.renderer.createElement('input');
this.renderer.setAttribute(rendInput, 'name', 'corp_name2');
this.renderer.setAttribute(rendInput, 'HanToZen', '');
this.renderer.appendChild(this.element, rendInput);
}
}
han-to-zen.directive.ts
import {OnInit, Directive, ElementRef, HostListener} from '@angular/core';
import { convertHAN2ZEN } from "./util";
@Directive({
selector: '[HanToZen]'
})
export class HanToZenDirective implements OnInit {
private element: HTMLInputElement;
constructor(
private elementRef: ElementRef,
) {
this.element = this.elementRef.nativeElement;
}
ngOnInit(){
this.element.value = convertHAN2ZEN(this.element.value);
}
@HostListener("blur", ["$event.target.value"])
onBlur(value){
this.element.value = convertHAN2ZEN(value);
}
}
directive-test.component.html
<h2>Directive Test</h2>
<form #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
<!-- firstのHanToZenは問題なく動作する -->
<input name="first" [(ngModel)]="first" HanToZen>
<!-- corp_nameにsetAttributeしたHanToZenは動作しない -->
<input name="corp_name" value='100' [(ngModel)]="corp_name" >
<button>Submit</button>
</form>
<動作環境>
Angular CLI: 6.1.3
Node: 8.11.3
OS: win32 x64
Angular: 6.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.6.5
@angular-devkit/build-angular 0.6.5
@angular-devkit/build-optimizer 0.6.5
@angular-devkit/core 0.6.5
@angular-devkit/schematics 0.7.3 (cli-only)
@angular/cli 6.1.3
@ngtools/webpack 6.0.5
@schematics/angular 0.7.3 (cli-only)
@schematics/update 0.7.3 (cli-only)
rxjs 6.2.0
typescript 2.7.2
webpack 4.8.3