在Angular 5中动态添加生命周期方法

时间:2018-08-03 18:36:03

标签: angular typescript

我有一个Angular 5应用程序,该应用程序具有一个类,该类为其子模板之一使用第3方库。我在组件中使用了两个模板,并希望为它们覆盖不同的行为,同时保持视图模板一致(避免重复两次复制第三方模板,当库更改时不会更新)。 )。这是模板的摘录:

<tree #bookmap [value]="bookmapModel"></tree>
<tree #repository [value]="repositoryModel"></tree>

在控制器中,我在此处设置覆盖库的方法onNodeClick(event: any, node: TreeNode)

@ViewChild('repository') set repo(tree: Tree) {
  if(tree) {
    tree.onNodeClick = this.onNodeClick.bind(this);
  }
}

与预期的一样,完全按照我想要的方式工作,并且效果完美。对于另一个,我想重写一个角度生命周期函数(ngOnChanges),特别是在库类的声明中未定义的函数(我的意思是说类声明不包括implement OnChanges行)。我尝试做同样的事情:

@ViewChild('bookmap') set bookmap(tree: Tree) {
  if(tree) {
    tree.ngOnChanges = this.onChanges.bind(this);
  }
}

在逻辑上应该给出编译错误。然后我尝试使用属性符号和原型:

@ViewChild('bookmap') set bookmap(tree: Tree) {
  if(tree) {
    tree['ngOnChanges'] = this.onChanges.bind(this);
  }
}

@ViewChild('bookmap') set bookmap(tree: Tree) {
  if(tree) {
    Tree.prototype['ngOnChanges'] = this.onChanges.bind(this);
  }
}

这似乎是等效的,我没有编译问题,但是在这里出现运行时错误

ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

有没有一种方法可以添加生命周期函数?从错误中可以推断出,当生命周期循环遇到函数时,已设置但未运行(抛出错误)。

1 个答案:

答案 0 :(得分:0)

该错误很可能是因为tree实例不再接收对ngOnChanges的调用。所以它的内部状态坏了。 做您正在做的事情的一个很好的理由,但是如果您必须尝试这样做的话。

@ViewChild('bookmap') set bookmap(tree: Tree | OnChanges) {
    if(tree) {
       const previousOnChanges = tree.ngOnChanges;
       tree.ngOnChanges = (changes: SimpleChanges) => {
           if(previousOnChanges) {
               previousOnChanges(changes);
           }
           this.onChanges(changes);
       }
    }
}

我不知道这是否会产生您期望的结果。

仅供参考:如果您将类型定义为Tree | OnChanges,则ngOnChanges如果引用它,则不应生成编译错误。