[英]Angular2 on focus event to add class
I'm looking to update an Angular 1 app to Angular 2 and am having an issue with one of my old directives. 我正在寻找将Angular 1应用程序更新为Angular 2并且我的旧指令存在问题。
The idea is simple. 这个想法很简单。 When an input field is focused a class should be added (md-input-focus) and another be removed (md-input-wrapper).
当聚焦输入字段时,应添加一个类(md-input-focus),另一个类被删除(md-input-wrapper)。 Then this process should be reversed on "blur" event - ie focus lost.
然后这个过程应该在“模糊”事件上反转 - 即焦点丢失。
My old directive simply included the lines 我的旧指令只包括行
.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');
})
}
etc... 等等...
I obviously have the classic start to my directive but have run out of.....skill 我显然对我的指示有经典的开始但是已经没有.....技能了
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
}
}
Any help would be appreciated. 任何帮助,将不胜感激。
UPDATE: 更新:
The HTML would look like (before the input element was focused): HTML看起来像(在输入元素被聚焦之前):
<div class="md-input-wrapper">
<input type="text" class="md-input">
</div>
and then 接着
<div class="md-input-wrapper md-input-focus">
<input type="text" class="md-input">
</div>
after. 后。
The input element is the only one which can receive a focus event (and therefore the target for the directive) however the parent <div>
requires the class addition and removal. input元素是唯一可以接收焦点事件(因此是指令的目标)的元素,但是父
<div>
需要添加和删除类。
Further help 进一步帮助
Please see Plunker for help/explanation - would be great if someone could help 请向Plunker寻求帮助/解释 - 如果有人可以提供帮助,那就太棒了
Update 更新
@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);
}
}
Original 原版的
This can easily be done without ElementRef
and Renderer
(what you should strive for in Angular2) by defining host bindings: 这可以通过定义主机绑定在没有
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;
}
}
or a bit more terse 或者更简洁一点
@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;
}
}
I tried it only in Dart where it works fine. 我只在Dart尝试过它可以正常工作。 I hope I translated it correctly to TS.
我希望我把它正确地翻译成TS。
Don't forget to add the class to the directives:
of the element where you use the directive. 不要忘记将类添加到
directives:
使用指令的元素。
In addition to previous answers, if you don't want to add a directive, for the specific component (you already have a directive for a parent component, you are using Ionic 2 page or something else), you inject the renderer by adding private _renderer: Renderer
in the page constructor and update the element using the event target like this: 除了以前的答案,如果您不想为特定组件添加指令(您已经有父组件的指令,您正在使用Ionic 2页面或其他内容),则通过添加
private _renderer: Renderer
注入渲染器private _renderer: Renderer
页面构造函数中的private _renderer: Renderer
并使用事件目标更新元素,如下所示:
html: HTML:
(dragstart)="dragStart($event)"
TS: TS:
dragStart(ev){
this._renderer.setElementClass(ev.target, "myClass", true)
}
Edit: to remove the class just do: 编辑:删除类只是做:
dragEnd(ev){
this._renderer.setElementClass(ev.target, "myClass", false)
}
The name of the selector has to be inside "[ ]", as shown below 选择器的名称必须在“[]”内,如下所示
@Directive({
selector: '[.mdInput]',
host: {
'(focus)':'_setInputFocus(true)',
'(blur)':'_setInputFocus(false)',
'[class.md-input-focus]':'inputFocusClass'
}
})
If you want to catch the focus / blur events dynamiclly on every input on your component : 如果要在组件的每个输入上动态捕获焦点/模糊事件:
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');
});
});
}
}
Checkout the full code here : https://stackblitz.com/edit/angular-wtwpjr 在这里查看完整代码: https : //stackblitz.com/edit/angular-wtwpjr
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.