2016-01-14 22 views
6

我正在更新Angular 2的Angular 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 - 將是巨大的,如果有人可以幫助

回答

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

原始

這很容易b Ë沒有ElementRefRenderer(你應該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; 
     } 
} 

我想它只是在DART它工作正常。我希望我把它正確地翻譯成TS。

不要忘記將該類添加到使用該指令的元素的directives:

+0

我理解你的代碼岡特的邏輯,但我認爲它不太適合。該類應該被添加到父元素。 HTML:

這是我有點卡住,因爲我不知道如何引用指令觸發元素的父元素? –

+0

好的,但父母不是父母的組件,但父母的標籤?在這種情況下,你需要'ElementRef'。在Angular中沒有'最接近的()'。你仍然想使用它,或者只是'.parentElement'好嗎? –

+0

我已更新我的問題,以顯示指令應附加到的HTML,以防情況:) –

0

選擇的名稱必須是內部的「[]」,如下圖所示

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

除了以前的答案,如果你不想添加指令,爲特定組件(你已經有了,您可以通過在頁面構造函數添加private _renderer: Renderer注入渲染器和使用活動對象這樣的更新元素的指令的父組件,您使用的離子2頁或別的東西):

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:Event){.... –