Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
698 views
in Technique[技术] by (71.8m points)

angular - Attribute directive with ngModel to change field value

I want to change (force) input field values while typing using a attribute Directive. With it I would like to create directives like uppercase, lowercase, maxlength, filterchar, etc. to be used on input fields on forms. I found this example: Angular 2 Attribute Directive Typescript Example but this doesn't seem to work. Maybe it did for an earlier build of Angular2. It is however exactly what I would like to do.

When I create a directive like this:

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);
    }
}

And use it on a form like this:

<input type="text" class="form-control" [(ngModel)]="field.name" ngControl="name" #name="ngForm" required uppercase>

(and register NgModel as a provider). I get an

undefined this.model.value.

I can use $event.target.value = $event.target.value.toUpperCase() (when passing $event with the onInputChange()) and that works for the view (it does show the input as uppercase. But it doesn't update the bind field "field.name".

So how to create an Angular2 attribute directive that does this?

-- EDIT --

After some further investigation I managed to get what I want. The answer Günter provided is closer to my original intention and perhaps better. But here is another way:

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)
    }
}

As I said I'm not sure if this is also a good way to do this so comments are welcome.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Although Günter's answer looks promising, there is a bug in that the final value in the model has the last entered letter in lowercase.

See here:

https://plnkr.co/edit/SzxO2Ykg2pKq1qfgKVMH

Please use the answer provided in the question. It works correctly.

@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)
    }
}

https://plnkr.co/edit/oE3KNMCG7bvEj8FV07RV


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...