【问题标题】:Angular 7: custom class decorator destroy component scopeAngular 7:自定义类装饰器破坏组件范围
【发布时间】:2019-03-29 21:13:12
【问题描述】:

我有一个装饰器,在 ngOnInit 上写一个 console.log

log.decorator.ts

export function Log(): ClassDecorator {

    // Decorator Factory
    return (target: Function) => {

        const ngOnInit: Function = target.prototype.ngOnInit;
        target.prototype.ngOnInit = ( ...args ) => {

            console.log('ngOnInit:', target.name);

            if ( ngOnInit ) {
                ngOnInit.apply(this, args);
            }
        };
    };
}

和一个使用@Log() 并导入ngOnInit 中使用的服务的HelloComponent

hello.component.ts

import { Component, Input, OnInit } from '@angular/core';
import { Log } from './log.decorator';
import { HelloService } from './hello.service';

@Component({
  selector: 'hello',
  template: `<p>Hello! thanks for help and open the browser console for see the error!</p>`,
  styles: [``]
})
// if you remove @Log(), helloService.sayHello() works!
@Log()
export class HelloComponent implements OnInit  {

  constructor(private helloService: HelloService){}

  ngOnInit(){
    this.helloService.sayHello();
  }
}

但这会导致异常:

ERROR TypeError: Cannot read property 'sayHello' of undefined

如果我从HelloComponent 中删除@Log(),它会起作用!

装饰器似乎破坏了组件范围:

ngOnInit.apply(this, args); // line 13: log.decorator.ts

在此调用之后,this.helloServiceHelloComponentngOnInit 中是undefined,但没有@Log()this.helloService 是一个HelloService 实例。

我该如何解决这个问题?

Stackblitz 上的实时示例: https://stackblitz.com/edit/angular-7hhp5n

【问题讨论】:

  • 我宁愿说没有this上下文。
  • 尝试删除“.prototype”,让“target.prototype.ngOnInit”变成“target.ngOnInit”。
  • 关于第一条评论:有一个这样的上下文,但很可能不是你想要的。为新的 ngOnInit 函数使用普通函数(不是箭头函数),因为您希望 this 上下文成为类的一个,而不是装饰器的一个(target.prototype.ngOnInit = ( ...args ) =&gt; { 变为 target.prototype.ngOnInit = function( ...args ) {

标签: arrays angular typescript angular7


【解决方案1】:

箭头函数强制上下文this成为封闭的词法上下文,它是Log函数的执行上下文。

要拥有组件上下文,您应该使用简单的函数表达式:

target.prototype.ngOnInit = function( ...args ) {
   ...
}

Forked Stackblitz

【讨论】:

    猜你喜欢
    • 2012-06-19
    • 2020-05-19
    • 2019-03-21
    • 1970-01-01
    • 2021-07-05
    • 2023-04-03
    • 1970-01-01
    • 2018-01-12
    • 2013-02-06
    相关资源
    最近更新 更多