手风琴 https://angular.carbondesignsystem.com/?path=/story/components-accordion—basic
组件及属性
- ibm-accordion
- Input
- align: start|end = end
- skeleton: boolean = false;
- Input
- ibm-accordion-item
- Input
- title: string| TemplateRef
; - context: Object | null = null;
- id =
accordion-item-${AccordionItem.accordionItemCount}
- skeleton = false;
- title: string| TemplateRef
- Output
- Input
@Component({
selector: ‘my-app’,
template: <h4>Welcome to Angular World</h4>
<exe-parent>
<exe-child></exe-child>
</exe-parent>
,
})
**ContentChild** 是属性装饰器,用来从通过 Content Projection 方式设置的试图中获取匹配的元素。
**ContentChildren** 属性装饰器,和 ContentChild相比,就是获取匹配的多个元素,返回的结果是一个 QueryList 集合。
**那 ContentChildren 和 ViewChildren 有啥区别呢?**
- 在父组件的开始结束标签中间放入的 元素,成为 ContentChildren.
- 在组件自己的模板中定义的内容,是组件的一部分,称为 ViewChildren.
**ContentChild 和 ViewChild 区别?**
- ContentChild 用于获取通过内容投影方式设置到试图中的元素。
- ViewChild 用于从模板中获取匹配的元素
- 在父组件的 ngAfterContentInit 生命周期中,才能获取通过 ContentChild 查询的元素
- 在父组件的 ngAfterViewInit 生命周期中,才能获取通过 ViewChild 查询的元素。
相关文章
- [https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/](https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/)
- [https://segmentfault.com/a/1190000008707828](https://segmentfault.com/a/1190000008707828) Angular2 ContentChild & ContentChildren
<a name="sbhI0"></a>
### ngTemplateOutlet/ngTemplateOutletContext 使用
> [https://codesandbox.io/s/strange-bartik-9vkx8j?file=/src/app/app.component.ts](https://codesandbox.io/s/strange-bartik-9vkx8j?file=/src/app/app.component.ts) 实时尝试
```typescript
@Component({
selector: '',
template: `
<!--
这里即实现了动态展示模板,并且 ng-container 仅仅是站位标签,
实际dom渲染后并不会有ng-container这一层显示。
<ng-container *ngTemplateOutlet="estimateTemplate" *ngTemplateOutletContext="ctx"></ng-container>
-->
<ng-container *ngTemplateOutlet="estimateTemplate; context: ctx"></ng-container>
<!--
注意,这里的let-xxx,这个xxx是模板中能够使用的变量
estimate 则是 ts 中定义的ctx的属性值。这个对应关系需要注意
-->
<ng-template #estimateTemplate let-lessonsCounter="estimate">
<div> Approximately {{lessonsCounter}} lessons ... </div>
</ng-template>
`})
export class AppoComponent {
total = 10;
ctx = { estimate: this.total }
}
/*
* 或者下面的方式也可以
* 上面是简写,这里是完整写法。
*/
@Component({
selector: "app-root",
template: `
<!--
这里的 $implicit 看着有点怪,不过算是固定写法,
可以看的到,还可以传入其他参数,如示例的 idx。
-->
<ng-container
[ngTemplateOutlet]="estimateTemplate"
[ngTemplateOutletContext]="{ $implicit: estimate, idx: 1 }"
></ng-container>
<ng-template #estimateTemplate let-estimate let-position="idx">
<div>Approximately {{ estimate }} lessons ...</div>
<div>positoin = {{position}}</div>
</ng-template>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent {
total = 10;
estimate = 20;
}
参考
- https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/
- https://indepth.dev/posts/1405/ngtemplateoutlet
HostBinding/HostListener
HostBinding 和 HostListener 长得很像,先看一个 HostListener 的 example: ```typescript import { Directive, ElementRef, Renderer, HostListener } from ‘@angular/core’;
@Directive({ selector:’[appChbgcolor]’ }) export class ChangeBgColorDirective { constructor(private el: ElementRef, private renderer: Renderer) { }
// 这里监听了 mouseover 事件 // 当鼠标移动到该 host 组件时,执行其中的逻辑 @HostListener(‘mouseover’) onMouseOver() { this.ChangeBgColor(‘red’) }
@HostListener(‘click’) onClick() { // click event }
@HostListener(‘mouseleave’) onMouseLeave() { // mouseleave event }
ChangeBgColor(color: string) { this.renderer.setElementStyle(this.el.nativeElement, ‘color’, color); } }
// 使用该 directive `
{{title}}
所以该 example 可以看出 **HostListener 指令的作用是处理来自host(托管)元素的事件**。
再来看一个 HostBinding 的 example:
```typescript
// 这里使用 border 变量绑定了 host 元素的 border 属性
@HostBinding('style.border') border: string;
@HostListener('mouseover') onMouseOver() {
// 这里修改 border 变量的值,来达到修改 host 元素 border 属性的目的
this.border = '5px solid green'
}
所以,可以看出 HostBinding 的作用就是修改 host 元素的属性。
参考
到这里我们对 accordion 组件也有了一定的了解了。
朋友你好,如果你对我的文章感兴趣,欢迎关注我的 Github (https://github.com/llccing),或者掘金 (https://juejin.cn/user/3227821867281079),或者语雀 (https://www.yuque.com/uov16w),感谢你的支持!