angular - 在嵌入的组件中使用父范围/方法/属性
问题描述
我尝试使用嵌入 n angular6 并且无法使我的范围变直。
<component-smart1
[someObject]="myObject"
[someService]="saidService">
<component-dumb-1
[specificObject]="getSpecificObject()"></component-dumb-1>
<component-dumb-2
[specificObject]="getSpecificObject()"
(someEvent)="handleEvent()"></component-dumb-2>
</component-smart1>
现在我希望哑组件(component-dumb-1
,component-dumb-2
)使用智能组件(component-smart1
)范围/方法/属性。
我的目标是能够在嵌入中用不同的组件组成不同的变体,所有这些都使用智能组件中的相同方法。例如:
<component-smart1
[someObject]="myObject"
[someService]="saidService">
<component-dumb-1
[specificObject]="getSpecificObject()"></component-dumb-1>
<component-dumb-2
[specificObject]="getSpecificObject()"
(someEvent)="handleEvent()"></component-dumb-2>
<component-dumb-3
[specificObject]="getSpecificObject()"
(someOtherEvent)="handleOtherEvent()"></component-dumb-3>
</component-smart1>
这可能吗?
解决方案
首先,在 Angular >= 2.x 中不再有作用域。组件模板的执行上下文总是它的组件类。但是,有几种方法可以在 和 之间进行parent => child
通信child => parent
。
第一种方法是使用@ContentChildren
将返回一个QueryList
. 这需要您添加模板引用变量,例如#myChild
. 这就是您的模板的样子:
<component-smart1>
<component-dumb-1 #myDumbChild></component-dumb-1>
<component-dumb-2 #myDumbChild></component-dumb-2>
</component-smart1>
使用@ContentChildren
装饰器,您可以查询这些引用变量并访问哑组件公共 API。
另一种方法是利用 DI 系统的强大功能。例如,您可以在子组件级别配置提供程序,使用抽象类作为注入令牌和策略useExisting
。这将允许您查询一个令牌以获取特定类型的所有内容子项。这是一个例子:
abstract class MyDumbComponent {
// some properties here
// some methods here
};
@Component({
selector: 'my-dumb-component',
providers: [
{ provide: MyDumbComponent, useExisting: DumbComponentA }
]
})
export class DumbComponentA implements MyDumbComponent {
...
}
注意,我在这里使用了一个抽象类作为标记,因为接口在编译后会消失,其次,我喜欢为具有相同方法的组件定义一些通用的“接口”。
在您的父组件中,您可以像这样查询它们:
@Component({
...
})
export class ParentSmartComponent { }
@ContentChildren(MyDumbComponent) myDumbComponents: QueryList<MyDumbComponent>;
ngAfterContentInit() {
// here you'll have access to your dumb components
}
}
第三种首选方法是使用@Output
's. 虽然上述方法在某些情况下可以正常工作,并且如果我理解正确,您希望从子组件与父组件进行通信。以上所有内容都将父组件置于驾驶员座位上,这意味着它们并没有真正列出某些事件,而是可以访问子组件的 API。@Output
另一方面,允许孩子通知其父母发生了什么事。然后父级可以监听这个事件并执行一些方法或任务。
如前所述,在大多数情况下,这是子组件和父组件之间通信的首选方式,因为它不会将您的子组件与父组件紧密耦合,反之亦然。哑组件仍然非常可重用,并且仅将一些事件分派到外部,然后父组件可以侦听并采取相应的行动。
这也允许您根据自己的喜好组合组件。您可以在智能组件中使用任何哑组件。这里唯一的要求是它们发出事件以通知其父级。
为了完整起见,您还可以将智能组件注入到哑组件中。这就是它的样子:
@Component({
...
})
export class MyDumbComponent {
constructor(private smartComponent: ParentSmartComponent) { }
}
但是,我也不推荐这种方法,因为它再次将您的愚蠢组件与您的智能组件紧密耦合。正如@n-sokolowski 已经提到的,内容投影可以用作组合的手段,并且您的组合组件应该尽可能可重用和通用。
总而言之,只需@Output
在您的哑组件中使用 ' 并发出父组件随后可以侦听的特定事件。
推荐阅读
- c# - 使用 .Net Core 创建时未保存会话
- storyboard - xcode11中的情节提要在旧项目中不起作用
- python - 如果条件不适用于 django 模板中的字符串变量
- ember.js - 生成与教程不同的模型语法
- ios - SKShapeNode fillColor 添加了 3 个绘图调用
- c# - 如何在更新操作期间将记录与 Entity Framework Core 同步为一对多关系?不添加新实体,只是同步
- angular - 我如何告诉父窗口从对话框中刷新其网格?
- flutter - Flutter:如何增加圆形图像中的边框半径?
- python - 如何查找单词是否在字符串中-FAST,python
- firemonkey - 在 TImageViewer 中重新定位图像