角度@input 值在构造函数中到达较晚 [英] angular @input value reaching late in constructor

查看:12
本文介绍了角度@input 值在构造函数中到达较晚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

指令

如果指令的构造函数中 subscribe 代码下方存在,则权限和身份验证可用,如果它被注释掉,则 @Input() 变量未定义.

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

下面是完整的指令代码

@Directive({选择器:'[授权我]'})导出类 AuthorizedDirective 实现 OnInit {@Input() 权限:字符串;@Input() 身份验证:字符串;私人用户:任何;构造函数(私有 elementRef:ElementRef,私有 currentUserService:userService){this.elementRef.nativeElement.style.display = 'none';this.currentUser = this.userService.userAuthorizations;/*this.currentUserService.getUser().subscribe((user) => {this.user = 用户;如果(this.authorized()){this.elementRef.nativeElement.style.display = 'block';}});*/}公共授权(){返回 this.user ||授权;}}

解决方案

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

循序渐进:

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

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

碰巧的是,observables 不会被处理,直到它们在 Angular 的区域中打勾.

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

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

I am writing a directive which has 2 @Input() variables and takes value from who ever using that directive like components.

Everything is fine. The only problem is that when there is a Observable.subscribe in the constructor, then @Input values are available in constructor and without Observable.subscribe the @Input() variable values are undefined

I know the better way to get @Input() variable of a directive is to access them inside a life cycle hook like ngOnInit or ngOnChange but my question is: why is this available in some cases and not available in other cases in a directive.

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

directive

If inside the directive's constructor below the subscribe code is there, then permission and auth is available, and if it's commented out then both of the @Input() variables are undefined.

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

Below is the entire directive code

@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;
  }
}

解决方案

This is a classic case of lifecycle hooks and asynchronous processing!

Taking it step by step:

  1. Angular instantiates the directive
  2. Angular processing things
  3. While processing it calls LifeCycle hooks to let you know what is happening.

Putting it all together what this means is Angular instantiates your directive AuthorizedDirective with its constructor function. In the context of that function permission, auth, and currentUser are all undefined because you have not set values to them yet. You then subscribe to changes that will happen in the service which is basically registering a function to occur AFTER we process observables.

As it happens observables, are not processed until a tick of the zone they are in for Angular.

The reason permission / auth are set in ngOnInit is because after Angular has instantiated your object, it parses it to see if you have any input or output values to use. If you do, it looks for the corresponding things that were set on the element and sets them before calling ngOnInit which is all before a zone tick happens.

So this is why you have the value in the subscribe and in ngOnInit but you don't have the value in the constructor itself.

这篇关于角度@input 值在构造函数中到达较晚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆