Вот мое более общее решение, которое в основном похоже на DefaultValueAccessor с добавленной текстовой функцией «трансформатор». Таким образом, вы будете использовать
<input mdInput [transformer]="uppercase" ...>
. В вашем компоненте у вас есть функция верхнего регистра (вы можете делать другие вещи помимо прописных букв, например, реализовать маску) ...
uppercase(value: string) {
return value.toUpperCase();
}
. ..
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { Directive, forwardRef, Input, OnChanges, SimpleChanges, Renderer, ElementRef } from '@angular/core';
import { TextMaskModule, MaskedInputDirective } from 'angular2-text-mask';
@Directive({
selector: 'input[transformer]',
// When the user updates the input
host: { '(input)': 'handleInput($event.target.value)', '(blur)': 'onTouched()' },
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextTransformerDirective), multi: true },
]
})
export class TextTransformerDirective implements ControlValueAccessor {
private inputElement: HTMLInputElement
lastValue = "";
onTouched = () => { }
onChange = (_: any) => { }
@Input('transformer')
transformer = (v: string) => v;
constructor(private renderer: Renderer, private element: ElementRef) {
}
handleInput(value: any) {
let newVal = this.transformer(value);
if (newVal != value || this.lastValue != newVal) {
this.lastValue = newVal;
this.renderer.setElementProperty(this.element.nativeElement, 'value', newVal);
this.onChange(newVal);
}
}
writeValue(value: any) {
let normalizedValue = value == null ? '' : value;
normalizedValue = this.transformer(normalizedValue);
this.renderer.setElementProperty(this.element.nativeElement, 'value', normalizedValue);
}
registerOnChange(fn: (value: any) => any): void { this.onChange = fn }
registerOnTouched(fn: () => any): void { this.onTouched = fn }
}
Вы неправильно фиксируете this
, обозначение стрелки не может использовать неявную ссылку this
, избегайте использования с JQuery
:
. Выражение функции стрелки имеет более короткий синтаксис чем выражение функции и не имеет своих собственных this, arguments, super или new.target. Эти функциональные выражения лучше всего подходят для не-методических функций и не могут использоваться в качестве конструкторов.
blockquote>Я переработал ваш код, чтобы он мог работать так, как вы ожидаете:
$("i").click(function() { changeColor($(this)); }); const changeColor = (obj) => { if (!obj.hasClass('clicked')) console.log('not clicked class'); }
.clicked { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <i class="fas fa-star fa-lg clicked">Button 1</i> <i class="fas fa-star fa-lg">Button 2</i> <i class="fas fa-star fa-lg">Button 3</i>
Вместо упомянутого this
вместо него можно использовать event.currentTarget
:
$("i").click(function(event)
{
changeColor($(event.currentTarget));
});
const changeColor = ($element) =>
{
if (!$element.hasClass('clicked'))
console.log('not clicked class');
}
.clicked {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<i class="fas fa-star fa-lg clicked">Button 1</i>
<i class="fas fa-star fa-lg">Button 2</i>
<i class="fas fa-star fa-lg">Button 3</i>
Использование this
в коде может привести к путанице, потому что вам нужно хорошо знать, как это работает. Многие люди склонны не использовать его из-за этого.
Имейте в виду, что я переименовал obj
в $element
. Я настоятельно рекомендую использовать префикс $
, чтобы показать, что эта переменная содержит jQuery.
Можете ли вы попробовать использовать element.is('.clicked')
? Вы можете попробовать более одной комбинации с , это ,