2016-01-14 34 views
6

Angular 1アプリをAngular 2に更新しようとしていて、古いディレクティブの1つに問題があります。フォーカスを追加してクラスを追加する際のAngular2

アイデアは簡単です。入力フィールドにフォーカスが当たったら、クラスを追加し(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 
     } 
} 

ご協力いただければ幸いです。

UPDATE:(入力要素が集中していた前)

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

さらにヘルプ

Please see Plunker for help/explanation - 誰かが簡単にBこれはできる

答えて

5

更新

@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); 
    } 
} 

オリジナル

を助けることができれば素晴らしいだろうeは、ホストのバインディングを定義することにより、(あなたがAngular2にのために努力すべきか)ElementRefRendererなしで行わ:

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

+0

を私はあなたのコードのギュンターのロジックを理解するが、私はそれが非常に収まらないと思う:ちょうど行うクラスを削除します。クラスは親要素に追加する必要があります。 HTML:

これは、ディレクティブがトリガーされた要素の親要素を参照する方法がわからないため、ちょっと立ち往生しています。 –

+0

親は親コンポーネントではなく親タグですか?この場合、 'ElementRef'が必要です。 Angularに 'nearest()'はありません。それでもそれを使用したいのですか、単に '.parentElement' okですか? –

+0

助けになる場合に指示文を添付するHTMLを表示するために私の質問を更新しました:) –

0

あなたが特定のコンポーネント(のために、ディレクティブを追加したくない場合は、以前の回答に加えて

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

下に示すように、セレクタの名前は、「[]」の内部である必要がありますあなたはすでに親コンポーネントの指示を持っていますが、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) 
} 
+0

非常に簡潔な答えと素晴らしい作品。私が行う唯一の変更は、それがタイプスクリプトなので、 "ev"に "イベント"の明示的なタイプを与えることです。 dragStart(ev:イベント){.... –

関連する問題