如何在角度 2 中向动态加载的子组件提供父组件的模型

How to provide a parent's model to a dynamically loaded child component in angular 2?

本文关键字:组件 模型 加载 动态      更新时间:2023-09-26

我在 Angular 1.x 应用程序中构建了许多指令。这些指令被我公司的各种内部应用程序使用。我希望这些应用程序不必更改其代码,而是在升级到 Angular 2.x 时在我的指令中抽象出许多语法更改。例如,假设我有以下指令:

<my-directive
    my-first-attribute="vm.someProperty" 
    my-second-attribute="vm.someFunction()"
></my-directive>

假设我无法从父组件的角度更改该语法这些属性需要转换为如下所示的内容:

[myFirstAttribute]="vm.someProperty"
(click)="vm.someFunction()"

曾经有一个编译函数,我可以在链接之前进行许多这些模板更改。现在我有了构造函数,我可以在其中拉入一个ElementRef,并DynamicComponentLoader

但是,如何为动态加载的组件提供vm

我试过:

this._loader.loadIntoLocation(SubCmp, this._el, 'container')
.then((compRef:ComponentRef) => {
  compRef.instance.vm = this.vm;
});

但是利用DynamicComponentLoader本身的组件不知道vm 。我真的不想更改调用组件的 HTML 语法,该组件反过来动态加载自己的子组件。这是我目前的 plunkr,它使用的是 Angular 2 beta 15。

原因是您忘记了括号[]

[model]="model.firstName"

如果我们忘记了括号,Angular 会将字符串视为常量,并使用该字符串初始化目标属性。它不计算字符串!

见文档,普伦克尔

假设您无法更改模板,则没有干净的方法来满足您的要求。我不建议使用它,但我想尝试angular-expressions库,检查这个 plunkr

想法是通过注入器层次结构获取父上下文并手动解析表达式。

//i don't fully understand why component index is 0
var context = injector.parent.getAt(0);
//create parser for this.model expression, i.e. 'model.firstName'
var evaluate = angularExpressions.compile(this.model);
//apply value from context
comp.model = evaluate(context);

对于使用共享服务与 DCL 添加的组件进行通信通常是要走的路。一些祖先提供服务,DCL 添加的组件注入它

@Injectable()
class Model {
  value:string = 'xxx';
}
export class InputCmp {
  constructor(private model:Model){}
  ...
}
@Component({
    selector: 'textbox',
...
    providers: [Model]
})
export class Textbox implements OnInit {
  ...
}

普伦克示例