【问题标题】:How to use directive on data value?如何对数据值使用指令?
【发布时间】:2023-03-24 17:29:01
【问题描述】:

如何对数据值使用指令?

<div class="col-12 data" appPhoneNumber>
    {{data.phoneNumber}}
</div>

appPhoneNumber 是我的指令,而 data.phoneNumber 是我想要使用它的值。我尝试过这种方式,但出现错误:

Error: StaticInjectorError(AppModule)[PhoneNumberDirective -> NgControl]: StaticInjectorError(Platform: core)[PhoneNumberDirective -> NgControl]: NullInjectorError: No provider for NgControl!

我有点不知所措,我对指令没有太多经验

编辑以包含指令代码:

@Directive({
  selector: '[appPhoneNumber]'
})
export class PhoneNumberDirective {

  constructor(public ngControl: NgControl) { }
  @Input('appPhoneNumber') appPhoneNumber;

  @HostListener('ngModelChange', ['$event'])
  onModelChange(event) {
    this.onInputChange(event);
  }

  onInputChange(event){
    let newVal = event.replace(/\D/g, '');
    if(newVal.length === 0){
      newVal = '';
    } else if(newVal.length<=3){
      newVal = newVal;
    } else if(newVal.length<=6){
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})/, '$1.$2');
    } else if(newVal.length<=10){
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,4})/, '$1.$2.$3');
    } else {
      newVal = newVal.substring(0, 10);
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,4})/, '$1.$2.$3');
    }
    this.ngControl.valueAccessor.writeValue(newVal);
  }
}

【问题讨论】:

  • 这个指令应该做什么?它的代码在哪里?
  • 您应该使用@Directive 注释并指定具有相同名称的@Input@Directive({ selector: '[appPhoneNumber]' }) 然后 @Input('appPhoneNumber') appPhoneNumber; 在指令的类声明中。
  • @hilnius 我尝试使用 Input,但它仍然给我同样的错误
  • @bryan60 已更新。它只是应该为电话号码添加点。像这样:xxx.xxx.xxxx
  • 在输入中还是仅作为显示值?

标签: angular angular-directive


【解决方案1】:

您不能在没有角度输入的情况下使用带有 ngControl 注入的输入控件,这就是您收到 no provider 错误的原因。对于简单的显示值,您需要一个管道。首先将您的转换函数提取为可重用的东西:

function formatPhoneNumber(val) {
    let newVal = val.replace(/\D/g, '');
    if(newVal.length === 0){
      newVal = '';
    } else if(newVal.length<=3){
      newVal = newVal;
    } else if(newVal.length<=6){
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})/, '$1.$2');
    } else if(newVal.length<=10){
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,4})/, '$1.$2.$3');
    } else {
      newVal = newVal.substring(0, 10);
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,4})/, '$1.$2.$3');
    }
    return newVal;
}

并将它放在你的指令中,然后编写一个使用它的管道:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'phone'})
export class PhonePipe implements PipeTransform {
  transform(value: string): string {
    return formatPhoneNumber(value);
  }
}

像往常一样声明/导入它,然后像这样使用它:

<div class="col-12 data">
    {{data.phoneNumber | phone}}
</div>

【讨论】:

  • 我可以使用管道来输入和显示值吗?还是无论如何我都必须创建指令和管道?
  • 您需要一个用于显示数据的管道和一个用于格式化输入的指令。它们是根本不同的,你能做的最好的就是把实际的格式化功能拉出来,并按照建议在两个地方使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多