web-dev-qa-db-ja.com

クラスを追加するフォーカスイベントのAngular2

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>クラスの追加と削除が必要です。

さらなるヘルプ

ヘルプ/説明についてはプランカーを参照してください -誰かが助けることができれば素晴らしいでしょう

7
Mad Eddie

更新

@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:にクラスを追加することを忘れないでください。

5

以前の回答に加えて、特定のコンポーネントに対してディレクティブを追加したくない場合(親コンポーネントのディレクティブが既にある場合は、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)
}
4
user1928596

以下に示すように、セレクターの名前は「[]」内にある必要があります

@Directive({
  selector: '[.mdInput]',
  Host: {
    '(focus)':'_setInputFocus(true)',
    '(blur)':'_setInputFocus(false)',
    '[class.md-input-focus]':'inputFocusClass'
  }
})
0
Roman Alshehri

コンポーネントのすべての入力でフォーカス/ブラーイベントを動的にキャッチしたい場合:

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

0
abahet