指令不解析初始值

Posted

技术标签:

【中文标题】指令不解析初始值【英文标题】:Directive not parsing initial value 【发布时间】:2019-01-02 17:28:49 【问题描述】:

目前我正在研究一个指令,只要用户不关注输入字段,就必须将数字显示为货币。在我从服务器重新加载数据并为输入字段提供起始值之前,这一直很好用。

每当我初始化输入字段的值时,在用户聚焦并退出输入字段之前解析不会应用(这是正常行为)。即使用户尚未输入(焦点)并退出(模糊)该字段,我也正在尝试应用数字格式。

左侧字段是我加载页面时的输入,右侧字段是我关注它并退出该字段后的输入。即使用户尚未与输入进行交互,我也需要显示正确的表示。

我尝试在构造函数和 ngInit 上应用管道,但这些点的值仍然是“0”,所以我认为我不能那样做。我也尝试绑定 ngOnChanges 生命周期和 'change' hostListener 事件,但都不起作用。

有什么方法可以使这项工作发挥作用,或者这会成为我页面上的一项功能吗?

我的指令:

@Directive(
  selector: '[appCurrencyFormatter]'
)
export class CurrencyFormatterDirective implements OnInit, OnChanges 

    private el: htmlInputElement;

    constructor(
      private elementRef: ElementRef,
      private currencyPipe: CurrencyPipe) 
        this.el = this.elementRef.nativeElement;
    

    ngOnInit() 
      // This doesn't work. value at this point is an empty string.
      this.el.value = this.currencyPipe.transform(this.el.value);
    

    @HostListener('change', ['$event.target.value'])
    ngOnChanges(changes) 
        console.log('change'); // only triggers when user changes the value.
                               // Not when value is set during initialization.
    

    @HostListener('focus', ['$event.target.value'])
    onFocus(value) 
      this.el.value = this.currencyPipe.parse(value);
    

    @HostListener('blur', ['$event.target.value'])
    onBlur(value) 
      this.el.value = this.currencyPipe.transform(value);
    


我的 html 输入:

<input type="text"
       [(ngModel)]="testNumber"
       appCurrencyFormatter />

testNumber 只是在 ngOnInit()... 中的值 22221 上初始化

我目前正在使用最新版本的 angular6。

【问题讨论】:

也许你应该使用管道而不是指令 这可能与变更检测有关。 【参考方案1】:

那是因为指令需要时间来抓取模型。你可以尝试做这样的事情:

import  Directive, OnInit, ElementRef  from '@angular/core';

@Directive(
  selector: '[appMyDir]'
)
export class MyDirDirective implements OnInit 

  constructor(private el: ElementRef)  

  ngOnInit() 
    setTimeout(() => 
      console.log(this.el.nativeElement.value)
    , 0);
  


【讨论】:

这行得通!但这有点像黑客攻击(尽管我明白为什么这可以解决它)。如果没有更好的答案,我会将其标记为答案。【参考方案2】:

使用ngAfterViewChecked 生命周期挂钩代替ngOnInit。这样可以确保值已经初始化。

export class CurrencyFormatterDirective implements AfterViewChecked 
                                                   ^^^^^^^^^^^^^
 // ...

  ngAfterViewChecked() 
  ^^^^^^^^^^^^^^^
    this.el.value = this.currencyPipe.transform(this.el.value);
  

看看这个stackblitz

有关AfterViewChecked 的更多信息,请查看docs。

【讨论】:

我添加了这个,但是没有用。它仍然有相同的结果。控制台日志仍将 el 的值显示为空字符串。 抱歉,我使用了错误的生命周期挂钩。更新了我的答案

以上是关于指令不解析初始值的主要内容,如果未能解决你的问题,请参考以下文章

vue__模板解析3一般指令解析

华为OD机试 - 计算面积(Java) | 机试题+算法思路+考点+代码解析 2023

华为OD机试 - 计算面积(Java) | 机试题+算法思路+考点+代码解析 2023

SpringMVC源码解析- HandlerAdapter初始化

Gprinter光栅位图点阵数据解析工具

西门子TCP协议解析