Angular 1アプリをAngular 2に更新しようとしていますが、古いディレクティブの1つに問題があります。
アイデアは単純です。入力フィールドがフォーカスされている場合、クラスを追加し(md-input-focus)、別のクラスを削除する(md-input-wrapper)必要があります。次に、このプロセスは「ぼかし」イベントで逆にする必要があります。つまり、フォーカスが失われます。
私の古いディレクティブは単に行を含んでいました
.directive('mdInput',[
'$timeout',
function ($timeout) {
return {
restrict: 'A',
scope: {
ngModel: '='
},
link: function (scope, elem, attrs) {
var $elem = $(elem);
$elem.on('focus', function() {
$elem.closest('.md-input-wrapper').addClass('md-input-focus')
})
.on('blur', function() {
$(this).closest('.md-input-wrapper').removeClass('md-input-focus');
})
}
等...
私は明らかに私の指令の古典的なスタートを切っていますが、.....スキルが不足しています
import {Directive, ElementRef, Renderer, Input} from 'angular2/core';
@Directive({
selector: '.mdInput',
})
export class MaterialDesignDirective {
constructor(el: ElementRef, renderer: Renderer) {
// Insert inciteful code here to do the above
}
}
どんな助けでもいただければ幸いです。
更新:
HTMLは次のようになります(入力要素がフォーカスされる前):
<div class="md-input-wrapper">
<input type="text" class="md-input">
</div>
その後
<div class="md-input-wrapper md-input-focus">
<input type="text" class="md-input">
</div>
後。
入力要素は、フォーカスイベント(したがってディレクティブのターゲット)を受け取ることができる唯一の要素ですが、親<div>
クラスの追加と削除が必要です。
さらなるヘルプ
ヘルプ/説明についてはプランカーを参照してください -誰かが助けることができれば素晴らしいでしょう
更新
@Directive({selector: '.md-input', Host: {
'(focus)': 'setInputFocus(true)',
'(blur)': 'setInputFocus(false)',
}})
class MaterialDesignDirective {
MaterialDesignDirective(private _elementRef: ElementRef, private _renderer: Renderer) {}
setInputFocus(isSet: boolean): void {
this.renderer.setElementClass(this.elementRef.nativeElement.parentElement, 'md-input-focus', isSet);
}
}
オリジナル
これは、ホストバインディングを定義することにより、ElementRef
およびRenderer
(Angular2で努力すべきこと)なしで簡単に実行できます。
import {Directive, ElementRef, Renderer, Input} from 'angular2/core';
@Directive({
selector: '.mdInput',
Host: {
'(focus)':'_onFocus()',
'(blur)':'_onBlur()',
'[class.md-input-focus]':'inputFocusClass'
}
})
export class MaterialDesignDirective {
inputFocusClass: bool = false;
_onFocus() {
this.inputFocusClass = true;
}
_onBlur() {
this.inputFocusClass = false;
}
}
またはもう少し簡潔
@Directive({
selector: '.mdInput',
Host: {
'(focus)':'_setInputFocus(true)',
'(blur)':'_setInputFocus(false)',
'[class.md-input-focus]':'inputFocusClass'
}
})
export class MaterialDesignDirective {
inputFocusClass: bool = false;
_setInputFocus(isFocus:bool) {
this.inputFocusClass = isFocus;
}
}
私はそれがうまくいくダートでのみそれを試しました。 TSに正しく翻訳したといいのですが。
ディレクティブを使用する要素のdirectives:
にクラスを追加することを忘れないでください。
以前の回答に加えて、特定のコンポーネントに対してディレクティブを追加したくない場合(親コンポーネントのディレクティブが既にある場合は、Ionic 2ページなど)を使用しています。 )、ページコンストラクターにprivate _renderer: Renderer
を追加してレンダラーを挿入し、次のようにイベントターゲットを使用して要素を更新します。
html:
(dragstart)="dragStart($event)"
TS:
dragStart(ev){
this._renderer.setElementClass(ev.target, "myClass", true)
}
編集:クラスを削除するには、次のようにします。
dragEnd(ev){
this._renderer.setElementClass(ev.target, "myClass", false)
}
以下に示すように、セレクターの名前は「[]」内にある必要があります
@Directive({
selector: '[.mdInput]',
Host: {
'(focus)':'_setInputFocus(true)',
'(blur)':'_setInputFocus(false)',
'[class.md-input-focus]':'inputFocusClass'
}
})
コンポーネントのすべての入力でフォーカス/ブラーイベントを動的にキャッチしたい場合:
import { AfterViewInit, Component, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
name = 'Angular focus / blur Events';
constructor(private el: ElementRef) {
}
ngAfterViewInit() {
// document.getElementsByTagName('input') : to gell all Docuement imputs
const inputList = [].slice.call((<HTMLElement>this.el.nativeElement).getElementsByTagName('input'));
inputList.forEach((input: HTMLElement) => {
input.addEventListener('focus', () => {
input.setAttribute('placeholder', 'focused');
});
input.addEventListener('blur', () => {
input.removeAttribute('placeholder');
});
});
}
}
ここで完全なコードをチェックアウトしてください: https://stackblitz.com/edit/angular-wtwpjr