角度@input 值在构造函数中到达较晚

Ani*_*Das 2 angular-directive angular

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

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

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

<div authorizedme
     [permission]="'manager'"
     [auth]="department"
     class="col-2 data-object-link">your salary is $90,000,0000
Run Code Online (Sandbox Code Playgroud)

指示

如果在subscribe代码下方的指令构造函数中存在,则权限和身份验证可用,如果已注释掉,则两个@Input()变量都是undefined.

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

下面是整个指令代码

@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;
  }
}
Run Code Online (Sandbox Code Playgroud)

msa*_*ord 7

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

\n\n

来自另一个问题

\n\n
\n

实现此接口以在初始化指令的数据绑定属性后执行自定义初始化逻辑。ngOnInit 在第一次检查指令的数据绑定属性之后以及检查其任何子项之前立即调用。它仅在指令实例化时被调用一次。

\n
\n\n

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

\n\n
\n

构造函数与 Angular2 无关,它们是 TypeScript 的功能。在发生一些初始化或发生某些事件后,Angular 会调用生命周期钩子,以允许组件在某些情况下采取行动,并让其有机会在适当的时间执行某些任务。

\n
\n\n

那么,可以预料的是,您的数据绑定属性在构造函数中尚不可用。

\n


Ken*_*ard 5

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

一步一步来:

  1. Angular 实例化指令
  2. Angular 处理的东西
  3. 在处理时,它会调用 LifeCycle 钩子让您知道发生了什么。

总而言之,这意味着 Angular 使用其构造函数实例化您的指令 AuthorizedDirective。在该函数权限的上下文中,auth 和 currentUser 都是未定义的,因为您尚未为其设置值。然后,您订阅将在服务中发生的更改,该服务基本上是注册一个函数,以便在我们处理 observable 之后发生。

碰巧 observables,直到它们在 Angular 所在的区域的刻度线才被处理。

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

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

  • _这都是在区域刻度发生之前。_ - 实际上这是变化检测的一部分,它不会在“刻度”之前**发生,而是在刻度期间**发生。所有生命周期挂钩都是变更检测的一部分。阅读 [关于 Angular 中的变更检测您需要了解的一切](https://hackernoon.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f) 了解更多详细信息 (2认同)