angular @input 值在构造函数中迟到

angular @input value reaching late in constructor

我正在编写一个指令,它有 2 个 @Input() 变量,并从使用该指令(如组件)的人那里获取值。

一切都很好。唯一的问题是,当构造函数中有 Observable.subscribe 时,@Input 值在构造函数中可用,而没有 Observable.subscribe 时,@Input() 变量值是 undefined

我知道获取指令的 @Input() 变量的更好方法是在像 ngOnInitngOnChange 这样的生命周期钩子中访问它们,但我的问题是:这是为什么在指令中某些情况下可用,而在其他情况下不可用。

<div authorizedme
     [permission]="'manager'"
     [auth]="department"
     class="col-2 data-object-link">your salary is ,000,0000

指令

如果指令的构造函数中有 subscribe 代码,则许可和身份验证可用,如果它被注释掉,则两个 @Input() 变量都是 undefined

this.userService.getUser().subscribe((user) => {
  this.user = user;
  if (this.authorized()) {
    this.elementRef.nativeElement.style.display = 'block';
  }
});

下面是整个指令代码

@Directive({
  selector: '[authorizedme]'
})
export class AuthorizedDirective implements OnInit {

  @Input() permission: string;
  @Input() auth: string;
  private user: any;

  constructor(private elementRef: ElementRef, private currentUserService: userService) {
    this.elementRef.nativeElement.style.display = 'none';
    this.currentUser = this.userService.userAuthorizations;

    /*this.currentUserService.getUser().subscribe((user) => {
      this.user = user;
      if (this.authorized()) {
        this.elementRef.nativeElement.style.display = 'block';
      }
    });*/

  }

  public authorized() {
   return this.user || authorize;
  }
}

这是生命周期钩子和异步处理的经典案例!

一步一步来:

  1. Angular 实例化指令
  2. Angular 处理事情
  3. 在处理过程中,它会调用 LifeCycle 挂钩让您知道发生了什么。

将它们放在一起意味着 Angular 实例化您的指令 AuthorizedDirective 及其构造函数。在该函数权限的上下文中,auth 和 currentUser 都是未定义的,因为您还没有为它们设置值。然后,您订阅将在服务中发生的更改,该服务基本上是注册一个函数,以便在我们处理可观察对象之后发生。

碰巧可观察对象在 Angular 所在区域的一个刻度之前不会被处理。

在 ngOnInit 中设置 permission / auth 的原因是因为在 Angular 实例化您的对象后,它会解析它以查看您是否有任何输入或输出值要使用。如果你这样做,它会查找在元素上设置的相应内容并在调用 ngOnInit 之前设置它们,这一切都是在区域刻度发生之前。

所以这就是为什么您在订阅和 ngOnInit 中有值,但在构造函数本身中没有值。

不要尝试访问 constructor 中的 @Input(),请在 ngOnInit 生命周期挂钩中访问。构造函数几乎与 Angular 应用程序生命周期无关。

来自

Implement this interface to execute custom initialization logic after your directive's data-bound properties have been initialized. ngOnInit is called right after the directive's data-bound properties have been checked for the first time, and before any of its children have been checked. It is invoked only once when the directive is instantiated.

此外,构造函数不是 Angular 功能,它是 TypeScript 功能。直接引用 Günter 对上述链接答案的评论:

Contstructors are not related to Angular2, they are a TypeScript feature. Lifecycle hooks are called by Angular after some initialization took place or when some event happend to allow the component act on certain situations and to give it the chance to do some tasks at proper times.

那么,您的数据绑定属性在构造函数中尚不可用,这是意料之中的事。