角度@input值在构造函数中延迟到达

时间:2017-07-19 19:16:57

标签: angular angular-directive

我正在编写一个包含2 @Input()个变量的指令,并从那些使用该指令的人那里获取价值。

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

我知道获取指令的ngOnInit变量的更好方法是在ngOnChange<div authorizedme [permission]="'manager'" [auth]="department" class="col-2 data-object-link">your salary is $90,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;
  }
}

以下是整个指令代码

$result = DB::select("SELECT name FROM account_name WHERE name='".$name."'"); 

3 个答案:

答案 0 :(得分:4)

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

一步一步地采取行动:

  1. Angular实例化指令
  2. 角度处理事物
  3. 处理时会调用LifeCycle钩子让你知道发生了什么。
  4. 将这一切放在一起意味着Angular使用其构造函数实例化你的指令AuthorizedDirective。在该函数的上下文中,auth和currentUser都是未定义的,因为您还没有为它们设置值。然后,您订阅将在服务中发生的更改,这些更改基本上是在我们处理可观察对象之后注册的函数。

    因为它发生了可观察性,直到它们为Angular所在的区域打勾才会被处理。

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

    所以这就是你在subscribe和ngOnInit中有值的原因,但你没有构造函数本身的值。

答案 1 :(得分:3)

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

来自another question

  

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

此外,构造函数不是Angular特征,它是TypeScript特性。直接引用Günter对上述相关答案的评论:

  

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

然后,可以预料到构造函数中尚未提供数据绑定属性。

答案 2 :(得分:0)

然后,角度文件说,每当输入绑定属性发生更改时,您要检测到更改,就应该使用生命周期挂钩。构造函数是生命周期的早期阶段,您可以尝试在ngOnCanges中进行操作吗,它可能会帮助您解决问题