aeg*_*ger 4 javascript dependency-injection angular
我的问题与在同一页面上放置具有不同参数的相同组件有关。在这种情况下,它是一个包含来自第三方 Javascript 库 ( D3JS )的图表的组件,它需要一个 HTMLid属性来定位和修改组件的 HTML 内容。
现在这个id属性应该包含放置在页面上的每个图表的唯一字符串,如果我直接将它设置为来自父组件的字符串,它就可以正常工作:
<my-chart id="gaugeChart0"></my-chart>
我猜它工作的原因是,因为该id属性在组件创建时就存在,并且任何试图访问它的代码都可以立即完成。
然而,该图表又嵌入到引导程序 4 卡布局中,如下所示:
<div class="row">
<div class="col-6">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-5">
<my-chart id="gaugeChart0"></my-chart>
</div>
<div class="col-7">
... Some other widgets ...
</div>
</div>
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-5">
<my-chart id="gaugeChart1"></my-chart>
</div>
<div class="col-7">
... Some other widgets ...
</div>
</div>
</div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
现在为了使它更方便(并轻松地将单击事件绑定到整个块等),我想将整个部分提取<div class="card">到一个新组件中。
假设我将这个新组件称为 WidgetContainerComponent,它包含图表以及引导卡布局,包括在那里定义的其他小部件。
使用此包装器组件时的结果代码将是:
<div class="row">
<div class="col-6">
<widget-container chartId="gaugeChart0"></widget-container>
</div>
<div class="col-6">
<widget-container chartId="gaugeChart1"></widget-container>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
为了使其工作,WidgetContainerComponent有一个输入字段
@Input() chartId: string;
可以设置。
我想要做的是id将MyChartComponent的属性设置为已设置为的字符串chartId:
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-5">
<my-chart [id]="chartId"></my-chart>
</div>
<div class="col-7">
... Some other widgets ...
</div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为 angular 为id属性添加了一个前缀,导致类似ng-reflect-id.
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-5">
<my-chart [attr.id]="chartId"></my-chart>
</div>
<div class="col-7">
... Some other widgets ...
</div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
这导致MyChartComponent具有直接id属性,但它似乎只在组件生命周期的后期添加。
我还尝试仅在和 中初始化MyChartComponent 中的图表,但这不起作用。ngOnInitngAfterContentInit
非常欢迎任何建议或想法!
所以我找到了解决这个问题的方法。问题是双重的:
第一个问题与具有真实id属性的要求有关,而不ng-reflect-是以 angular为前缀的属性名称。
我不知道的是,从 Angular 4 开始,这个前缀被添加到任何@Input在开发模式下声明为组件变量的属性(有关深入解释,请参阅这篇文章)。
这个问题的解决方案是编写[attr.id]=chartId而不是[id]=chartId. 原因是在这种情况下我需要设置一个HTML 属性,但是使用方括号表示法创建了一个属性绑定。为了通过属性绑定语法动态设置 HTML 属性,您必须将前缀添加attr.到属性名称。
有关所有有效绑定语法的完整概述,请参阅Angular 文档。具体复习如何做属性绑定见本节。
第二个问题是我试图访问id尚未创建的组件的属性。这个问题与Angular的生命周期钩子有关,这里有不同的阶段。要全面了解 Angular 的生命周期挂钩,请参阅此页面。
因为我自己也不是很了解,这里我就简单的说一下。
Angular 带有一组固定的生命周期钩子,每次设置组件时都会调用这些钩子,并且也会以预定义的顺序调用。钩子定义如下:
_
需要注意的是,在一个步骤中创建或准备的元素只能在任何后续步骤中访问。就我而言,我将图表初始化的所有代码都放入ngAfterContentInit钩子中,但是该组件仅在ngAfterViewInit被调用时才完全加载。
最后的解决方案是将预初始化代码放入构造函数中,并将图表初始化代码放入ngAfterViewInit方法中。在此阶段,id属性已正确创建并可被图表访问。
| 归档时间: |
|
| 查看次数: |
9408 次 |
| 最近记录: |