使用 ngModel 的属性指令来更改字段值
Attribute directive with ngModel to change field value
我想在使用属性指令键入时更改(强制)输入字段值。我想用它创建指令,如大写、小写、maxlength、filterchar 等,以用于表单的输入字段。我找到了这个例子:Angular 2 Attribute Directive Typescript Example 但这似乎不起作用。也许它适用于 Angular2 的早期版本。然而,这正是我想做的。
当我创建这样的指令时:
import {Directive} from 'angular2/core';
import {NgModel} from 'angular2/common';
@Directive({
selector: '[ngModel][uppercase]',
host: {
'(input)' : 'onInputChange()'
}
})
export class UppercaseDirective{
constructor(public model:NgModel){}
onInputChange(){
var newValue = this.model.value.toUpperCase();
this.model.valueAccessor.writeValue(newValue);
this.model.viewToModelUpdate(newValue);
}
}
并在这样的表格上使用它:
<input type="text" class="form-control" [(ngModel)]="field.name" ngControl="name" #name="ngForm" required uppercase>
(并注册 NgModel
作为提供商)。我得到一个
undefined this.model.value.
我可以使用 $event.target.value = $event.target.value.toUpperCase()
(当用 onInputChange()
传递 $event
时),这适用于视图(它确实将输入显示为大写。但它不会更新绑定字段 "field.name".
那么如何创建执行此操作的 Angular2 属性指令?
-- 编辑--
经过进一步调查,我设法得到了我想要的东西。 Günter 提供的答案更接近我的初衷,也许更好。但这是另一种方式:
import {Directive, Input, Output, EventEmitter} from 'angular2/core';
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
正如我所说,我不确定这是否也是一个好方法,因此欢迎发表评论。
更新
这种方法不能正常工作。请参阅@RyanHow 的回答以获得更好的解决方案。
原创
@Directive({
selector: '[ngModel][uppercase]',
providers: [NgModel],
host: {
'(ngModelChange)' : 'onInputChange($event)'
}
})
export class UppercaseDirective{
constructor(private model:NgModel){}
onInputChange(event){
this.model.valueAccessor.writeValue(event.toUpperCase());
}
}
虽然 Günter 的回答看起来很有希望,但存在一个错误,即模型中的最终值最后输入的字母是小写的。
看这里:
https://plnkr.co/edit/SzxO2Ykg2pKq1qfgKVMH
请使用问题中提供的答案。它工作正常。
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
我遇到了同样的问题,我需要在 Angular 和 select2 中创建自定义 select。我创建了以下指令来使用属性指令和 ngModel
.
实现此目的
import {ElementRef, Directive, EventEmitter, Output, Input} from '@angular/core';
import {NgModel} from "@angular/forms";
declare let $;
@Directive({
selector: '[custom-select]',
providers: [NgModel]
})
export class CustomSelectComponent{
$eventSelect:any;
@Output() ngModelChange:EventEmitter<any> = new EventEmitter();
@Input() set ngModel(value:any){
//listen to the input value change of ngModel and change in the plugin accordingly.
if(this.$eventSelect){
this.$eventSelect.val(value).trigger('change',{fromComponent:true});
}
}
constructor(private elementRef: ElementRef) {}
ngOnInit(){
this.$eventSelect = $(this.elementRef.nativeElement);
this.$eventSelect.select2({minimumResultsForSearch:-1});
this.$eventSelect.on("change.select2", (event,data)=> {
//listen to the select change event and chanage the model value
if(!data || !data.fromComponent){ //dont change model when its chagned from the input change event
this.ngModelChange.emit(this.$eventSelect.val());
}
});
}
}
具有以下用法
<select custom-select [(ngModel)]="protocol.type">
<option value="1">option1</option>
<option value="1">option2</option>
</select>
要求我必须创建一个指令 trim 文本输入的前导和尾随空格。
我的解决方案:
import { Directive, ElementRef, HostListener, Output, EventEmitter } from '@angular/core';
import { NgModel } from "@angular/forms";
@Directive({
selector: '[text-trim]',
providers: [NgModel]
})
export class TextInputTrimDirective {
@Output() ngModelChange: EventEmitter<any> = new EventEmitter();
constructor(private el: ElementRef) {}
@HostListener('change') onInputChange() {
const value = this.el.nativeElement.value.trim();
this.ngModelChange.emit(value);
}
}
我想在使用属性指令键入时更改(强制)输入字段值。我想用它创建指令,如大写、小写、maxlength、filterchar 等,以用于表单的输入字段。我找到了这个例子:Angular 2 Attribute Directive Typescript Example 但这似乎不起作用。也许它适用于 Angular2 的早期版本。然而,这正是我想做的。
当我创建这样的指令时:
import {Directive} from 'angular2/core';
import {NgModel} from 'angular2/common';
@Directive({
selector: '[ngModel][uppercase]',
host: {
'(input)' : 'onInputChange()'
}
})
export class UppercaseDirective{
constructor(public model:NgModel){}
onInputChange(){
var newValue = this.model.value.toUpperCase();
this.model.valueAccessor.writeValue(newValue);
this.model.viewToModelUpdate(newValue);
}
}
并在这样的表格上使用它:
<input type="text" class="form-control" [(ngModel)]="field.name" ngControl="name" #name="ngForm" required uppercase>
(并注册 NgModel
作为提供商)。我得到一个
undefined this.model.value.
我可以使用 $event.target.value = $event.target.value.toUpperCase()
(当用 onInputChange()
传递 $event
时),这适用于视图(它确实将输入显示为大写。但它不会更新绑定字段 "field.name".
那么如何创建执行此操作的 Angular2 属性指令?
-- 编辑--
经过进一步调查,我设法得到了我想要的东西。 Günter 提供的答案更接近我的初衷,也许更好。但这是另一种方式:
import {Directive, Input, Output, EventEmitter} from 'angular2/core';
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
正如我所说,我不确定这是否也是一个好方法,因此欢迎发表评论。
更新
这种方法不能正常工作。请参阅@RyanHow 的回答以获得更好的解决方案。
原创
@Directive({
selector: '[ngModel][uppercase]',
providers: [NgModel],
host: {
'(ngModelChange)' : 'onInputChange($event)'
}
})
export class UppercaseDirective{
constructor(private model:NgModel){}
onInputChange(event){
this.model.valueAccessor.writeValue(event.toUpperCase());
}
}
虽然 Günter 的回答看起来很有希望,但存在一个错误,即模型中的最终值最后输入的字母是小写的。
看这里:
https://plnkr.co/edit/SzxO2Ykg2pKq1qfgKVMH
请使用问题中提供的答案。它工作正常。
@Directive({
selector: '[ngModel][uppercase]',
host: {
"(input)": 'onInputChange($event)'
}
})
export class UppercaseDirective{
@Output() ngModelChange:EventEmitter<any> = new EventEmitter()
value: any
onInputChange($event){
this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
}
}
我遇到了同样的问题,我需要在 Angular 和 select2 中创建自定义 select。我创建了以下指令来使用属性指令和 ngModel
.
import {ElementRef, Directive, EventEmitter, Output, Input} from '@angular/core';
import {NgModel} from "@angular/forms";
declare let $;
@Directive({
selector: '[custom-select]',
providers: [NgModel]
})
export class CustomSelectComponent{
$eventSelect:any;
@Output() ngModelChange:EventEmitter<any> = new EventEmitter();
@Input() set ngModel(value:any){
//listen to the input value change of ngModel and change in the plugin accordingly.
if(this.$eventSelect){
this.$eventSelect.val(value).trigger('change',{fromComponent:true});
}
}
constructor(private elementRef: ElementRef) {}
ngOnInit(){
this.$eventSelect = $(this.elementRef.nativeElement);
this.$eventSelect.select2({minimumResultsForSearch:-1});
this.$eventSelect.on("change.select2", (event,data)=> {
//listen to the select change event and chanage the model value
if(!data || !data.fromComponent){ //dont change model when its chagned from the input change event
this.ngModelChange.emit(this.$eventSelect.val());
}
});
}
}
具有以下用法
<select custom-select [(ngModel)]="protocol.type">
<option value="1">option1</option>
<option value="1">option2</option>
</select>
要求我必须创建一个指令 trim 文本输入的前导和尾随空格。 我的解决方案:
import { Directive, ElementRef, HostListener, Output, EventEmitter } from '@angular/core';
import { NgModel } from "@angular/forms";
@Directive({
selector: '[text-trim]',
providers: [NgModel]
})
export class TextInputTrimDirective {
@Output() ngModelChange: EventEmitter<any> = new EventEmitter();
constructor(private el: ElementRef) {}
@HostListener('change') onInputChange() {
const value = this.el.nativeElement.value.trim();
this.ngModelChange.emit(value);
}
}