簡體   English   中英

使用ngModel更改字段值的屬性指令

[英]Attribute directive with ngModel to change field value

我想在使用屬性Directive鍵入時更改(強制)輸入字段值。 有了它,我想創建一些指令,如大寫,小寫,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時)並且適用於視圖(它確實將輸入顯示為大寫。但它沒有' t更新綁定字段“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)
    }
}

正如我所說,我不確定這是否也是一個好方法,所以歡迎評論。

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

https://plnkr.co/edit/oE3KNMCG7bvEj8FV07RV

更新

這種方法不能正常工作。 請參閱@ 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());
  }
}

Plunker

我遇到了同樣的問題,我需要使用select2在Angular中創建自定義選擇。 我已經使用attribute指令和ngModel創建了以下指令來實現這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>

要求我必須創建一個指令來修剪文本輸入的前導和尾隨空格。 我的解決方案

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM