Javascript Angular2在焦点事件上添加类

Javascript Angular2在焦点事件上添加类,javascript,jquery,angular,angular-directive,Javascript,Jquery,Angular,Angular Directive,我希望将Angular 1应用程序更新为Angular 2,但我的一个旧指令有问题 这个想法很简单。当一个输入字段被聚焦时,应该添加一个类(md-input-focus),删除另一个类(md-input-wrapper)。然后这个过程应该在“模糊”事件中反转-即焦点丢失 我的旧指令只是包括了这些行 .directive('mdInput',[ '$timeout', function ($timeout) { return { restri

我希望将Angular 1应用程序更新为Angular 2,但我的一个旧指令有问题

这个想法很简单。当一个输入字段被聚焦时,应该添加一个类(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 md-input-focus">
   <input type="text" class="md-input">
</div>

之后

input元素是唯一可以接收焦点事件(因此也是指令的目标)的元素,但是父级
需要添加和删除类

进一步帮助


-如果有人能帮助更新,那就太好了

@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;
      }
}
我只在Dart试过,效果很好。我希望我把它正确地翻译成TS


不要忘记将类添加到使用该指令的元素的
指令:

选择器的名称必须位于“[]”内,如下所示

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

除了前面的答案之外,如果您不想添加特定组件的指令(您已经有了父组件的指令,您正在使用Ionic 2页或其他内容),通过在页面构造函数中添加
private\u renderer:renderer
注入渲染器,并使用事件目标更新元素,如下所示:

html:

TS:

编辑:要删除该类,只需执行以下操作:

dragEnd(ev){
    this._renderer.setElementClass(ev.target, "myClass", false)
}

如果要动态捕捉组件上每个输入上的聚焦/模糊事件:

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');
            });
        });
    }
}
从'@angular/core'导入{AfterViewInit,Component,ElementRef};
@组成部分({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent实现AfterViewInit{
名称='角度聚焦/模糊事件';
构造函数(专用el:ElementRef){
}
ngAfterViewInit(){
//document.getElementsByTagName('input'):对所有文档输入进行gell
const inputList=[].slice.call((this.el.nativeElement.getElementsByTagName('input'));
inputList.forEach((输入:HTMLElement)=>{
input.addEventListener('focus',()=>{
setAttribute('placeholder','focused');
});
input.addEventListener('blur',()=>{
input.removeAttribute(“占位符”);
});
});
}
}

在此处查看完整代码:

我理解您的代码Gunter的逻辑,但我认为它不太合适。该类应添加到父元素中。HTML:这就是我有点坚持的地方,因为我不知道如何引用被触发指令的元素的父元素?好的,但是父元素不是父组件,而是父标记?在这种情况下,您需要
ElementRef
。角度中没有最近的()。您是否仍要使用该指令,或者只是
.parentElement
确定?我已更新了我的问题,以显示该指令应附加到的HTML,以防有帮助:)我更新了我的问题。再一次,我希望我在从Dart翻译到TS时没有添加bug。谢谢Gunter。如果我的父母能工作,我会很高兴的。你能告诉我怎么用吗?您的代码在ts中工作,尽管这本书应该是布尔的:)答案非常简洁,效果非常好。我唯一要做的更改是,因为它是typescript,所以给“ev”一个显式类型的“Event”。dragStart(ev:事件){。。。。
dragStart(ev){
    this._renderer.setElementClass(ev.target, "myClass", true)
}
dragEnd(ev){
    this._renderer.setElementClass(ev.target, "myClass", false)
}
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');
            });
        });
    }
}