$('#sortable').find('li').each(function(){
var listId = $(this).attr("id");
});
Возможно, это сработает ...
Вот мое более общее решение, которое в основном похоже на 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 }
}
Вот мой рабочий код, я использую angular4
Это ваша директива для верхнего регистра
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appUpper]'
})
export class UpperDirective {
constructor(public ref: ElementRef) { }
@HostListener('input', ['$event']) onInput(event) {
this.ref.nativeElement.value = event.target.value.toUpperCase();
}
}
Это ваш html-код файла, в котором вы использовали прописную директиву
<input type="text" id="id" placeholder="id" tabindex="0" formControlName="id" appUpper>
pixelbits предоставил отличное решение, но оно не работает в последней версии Angular (v4.3.1), поскольку директивы обесцениваются из компонента. Мое решение основано на его ответе только, но работает с последним
. Я предоставляю общее решение с настраиваемой директивой атрибута с логическим вводом, который будет скрывать ввод в верхний регистр, если это правда.
upper-case.directive.ts:
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({
selector: '[UpperCase]',
host: {
'(input)': 'toUpperCase($event.target.value)',
}
})
export class UpperCaseTextDirective {
@Input('UpperCase') allowUpperCase: boolean;
constructor(private ref: ElementRef) {
}
toUpperCase(value: any) {
if (this.allowUpperCase)
this.ref.nativeElement.value = value.toUpperCase();
}
}
Вот соответствующий компонент приложения с шаблоном.
app.ts
//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {UpperCaseTextDirective} from './upper-case.directive'
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
Auto Capitalize True: <input [UpperCase]="true" type="text" #input />
<br/>
Auto Capitalize False: <input [UpperCase]="allowEdit" type="text"/>
</div>
`,
})
export class App {
name:string;
allowEdit:boolean;
constructor() {
this.name = `Angular! v${VERSION.full}`;
this.allowEdit= false;
}
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App,UpperCaseTextDirective ],
bootstrap: [ App ]
})
export class AppModule {}
Здесь Plnkr , которые демонстрируют это.
Как предложил @Eric Martinez, вы можете создать локальную переменную шаблона и привязать верхнюю строку к свойству value на входном событии:
<input type="text" #input (input)="input.value=$event.target.value.toUpperCase()" />
В качестве альтернативы вы можете сделать это директивой:
@Directive({
selector: 'input[type=text]',
host: {
'(input)': 'ref.nativeElement.value=$event.target.value.toUpperCase()',
}
})
export class UpperCaseText {
constructor(private ref: ElementRef) {
}
}
Чтобы использовать директиву, укажите UpperCaseText
в списке директив вашего компонента:
directives: [UpperCaseText]
<input type="text" #input (input)="input.value=$event.target.value.toUpperCase()" />
– RoninCoder
27 March 2016 в 23:52
Вот мое решение:
Использование хост-слушателя для прослушивания входного события, а затем принудительного его ввода в верхний регистр.
import {Directive, EventEmitter, HostListener, Output} from '@angular/core';
@Directive({
selector: '[ngModel][uppercase]'
})
export class UppercaseDirective {
@Output() ngModelChange: EventEmitter<any> = new EventEmitter();
value: any;
@HostListener('input', ['$event']) onInputChange($event) {
this.value = $event.target.value.toUpperCase();
this.ngModelChange.emit(this.value);
}
}
С помощью этой директивы вы можете легко вводить ввод в верхний регистр например:
<input type="text" class="form-control" placeholder="ID"
formControlName="id" [(ngModel)]="form.value.id" uppercase/>
По крайней мере, по моему опыту, я нашел два ответа здесь проницательными, но не работал сам по себе: из Thierry Templier (с первым комментарием), а из cal .
Я собрал части обоих, и придумал эту версию, которая теперь работает с Angular 4.1.1 в реактивной форме:
import { Directive, Renderer, ElementRef, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, DefaultValueAccessor } from '@angular/forms';
const LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => LowerCaseInputDirective),
multi: true,
};
@Directive({
selector: 'input[lowercase]',
host: {
// When the user updates the input
'(input)': 'onInput($event.target.value)',
'(blur)': 'onTouched()',
},
providers: [
LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR,
],
})
export class LowerCaseInputDirective extends DefaultValueAccessor {
constructor(renderer: Renderer, elementRef: ElementRef) {
super(renderer, elementRef, false);
}
writeValue(value: any): void {
const transformed = this.transformValue(value);
super.writeValue(transformed);
}
onInput(value: any): void {
const transformed = this.transformValue(value);
super.writeValue(transformed);
this.onChange(transformed);
}
private transformValue(value: any): any {
const result = value && typeof value === 'string'
? value.toLowerCase()
: value;
return result;
}
}
Это для нижнего регистра, но все верно и для верхнего строчка, просто переименуйте директиву, замените внутри selector
и transformValue
.
Edit: простой пример использования из HTML-кода с использованием такой директивы:
<input id="myField"
formControlName="myField"
type="text" class="form-control required"
lowercase>
Я бы создал пользовательскую реализацию ControlValueAccessor. Последнее соответствовало бы директиве, которая будет прослушивать входное событие хоста. Таким образом, вы сможете ввести в верхний регистр то, что вы заполняете пользователем. Элемент управления будет автоматически содержать значение в верхнем регистре.
Вот реализация:
@Directive ({
selector: 'input[uppercase]',
// When the user updates the input
host: { '(input)': 'onChange($event.target.value.toUpperCase())' }
})
export class UppercaseValueAccessor extends DefaultValueAccessor {
(...)
// When the code updates the value of the
// property bound to the input
writeValue(value:any):void {
if (value!=null) {
super.writeValue(value.toUpperCase());
}
}
}
Не забудьте зарегистрировать этот пользовательский атрибут значения в поставщиках директив. Таким образом ваш пользовательский атрибут значения будет использоваться вместо стандартного.
const UPPERCASE_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => UppercaseValueAccessor), multi: true});
@Directive ({
providers: [ UPPERCASE_VALUE_ACCESSOR ],
(...)
})
export class UppercaseValueAccessor ...
И добавьте директиву в атрибут директивы компонента, в котором вы хотите использовать этот подход.
См. Этот класс для более подробной информации:
Эта ссылка может давать дополнительные подсказки (см. раздел «Компонент, совместимый с NgModel»):
[class.invalid]="myControl.touched && !myControl.valid
), в ответ на входное событие мне нужно было вызвать super.writeValue(updatedValue); this.onTouched(); this.onChange(updatedValue);
– cghislai
13 April 2016 в 15:15
DefaultAccessor
. Почему бы не унаследовать от этого и добавить только то, что другое? – superjos 1 August 2017 в 23:50