首页 > 解决方案 > Angular - 如何使用模板中的实用功能

问题描述

我有一个 Helper 类,它定义了一个静态方法“keyDown”,它获取按下的键。

我在几个组件中使用它,它只是被定义为组件类上的一个方法,从模板中调用,如下所示:

     <input type="number"
       ...
       (keydown)="keyDown($event)"
       pattern="^(\d?[0-9]|[1-9]0)$"
       required/>

但是复制该代码并不好,因此我将其放入静态类中,如this question中所述

export abstract class Helper {
  public static keyDown($event: any) {...}
}

零件:

import { Helper } from '../../../utils/helper';

  constructor(
    private helper: Helper,
  ) { }

  get keyDown(v) { return Helper.keyDown(v); }

这不起作用,因为您不能将值传递给 getter。

那么如何才能拥有从不同组件的模板中调用的共享实用程序函数呢?

更新 - 我试过这个。

感谢@CharlesBarnes 的评论。这几乎奏效了!

我做了3个微妙但重要的改变:

  1. 类方法不再是静态的:
    export abstract class Helper {
      public keyDown($event: any) {...}
    }
  1. 注入的助手不再是私有的,而是公共的。这意味着模板现在可以看到辅助类中的所有方法,因此可以直接调用它们:
    import { Helper } from '../../../utils/helper';
    
      constructor(
        public helper: Helper,
      ) { }
  1. 最后,我更改了模板,在方法调用前加上注入类的名称(小写“helper”):
     <input type="number"
       ...
       (keydown)="helper.keyDown($event)"
       pattern="^(\d?[0-9]|[1-9]0)$"
       required/>

但它抛出一个

NullInjectioNError, no provider for 'Helper'

:(

这种方式意味着将 Helper 类转换为服务,并使其可注入。

...但是提供一些通用的帮助实用程序似乎有点过头了。

标签: angular

解决方案


这是一个非常好的开始。您已接近解决方案。

到目前为止,您只声明了一个abstract类,现在需要由另一个可以实例化的类来实现。

@Injectable()
export class MyHelper implements Helper {
  keyDown(e: KeyboardEvent){
    console.log(e)
  }
}

现在可以提供类。我会在组件级别这样做:

import { Component } from '@angular/core';
import { Helper } from './helper';
import { MyHelper } from './my-helper';

@Component({
  ...
  providers: [
    { provide: Helper, useClass: MyHelper }
  ]
})
export class AppComponent  {
  constructor(
    public helper: Helper,
  ) { }
}

HTML 保持原样。

(keydown)="helper.keyDown($event)"

我会说这实际上是一个很好的模式,因为另一个组件可能使用 keydown 处理程序的不同实现。这使代码在通过抽象类进行强类型化时保持解耦。


推荐阅读