간단하지만 맞춤형 아코디언 부품
34846 단어 webdevtypescriptjavascriptangular
아코디언
아코디언은 보통 수직으로 쌓인 제목 목록으로 누르면 내용을 표시합니다.아코디언이나 확장성은 거의 모든 UI 라이브러리의 일부로 간주됩니다.
각 재료를 살펴보면
Expansion Panel
(ref)이 있는데 Ng 가이드에서 간단한 Accordion
(ref)이라고 불린다.맞춤형 아코디언 만들기
우리가 세워야 할 것은 더욱 간단한 판본이다.여느 때와 마찬가지로, 그 배후의 모든 생각은 각도 변화의 가능성을 탐색하는 데 도움을 준다.이 블로그는 주로 Angular에서
Content Projection
(ref)을 사용하여 다시 사용할 수 있고 맞춤형 UI 구성 요소를 만드는 방법에 관한 것이다.우리는 어떠한 제3자 라이브러리에 의존하여 우리의 구성 요소를 구축하지 않을 것이다.우리는 이 글에서
Directives
, TemplateRef
, Animation
등을 사용할 것이다.계획
만약 우리가 아코디언 부품의 해부 구조를 본다면, 우리는 안에 있는 모든 다른 항목을 수용할 수 있는 주요 부용기가 필요하다.항목마다 제목과 내용 부분을 포함합니다.
내용 부분은 완전히 동태적이니 우리는 걱정할 필요가 없다.머리글의 내용:
건축 아코디언 부품
우선 구성 요소를 위한 전용 모듈을 만듭니다.모듈과 함께 만들어야 할 항목은 다음과 같습니다.
lib/
├─ accordion/
│ ├─ directives/
│ │ ├─ accordion-item.directive.ts
│ │ ├─ accordion-content.directive.ts
│ │ ├─ accordion-title.directive.ts
│ │ ├─ accordion-header.directive.ts
│ ├─ accordion.component.html
│ ├─ accordion.component.css
│ ├─ accordion.component.ts
│ ├─ accordion.module.ts
모듈의 모양은 다음과 같습니다.import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { AccordionComponent } from "./accordion.component";
import { AccordionItem } from "./directives/accordion-item.directive";
import { AccordionContent } from "./directives/accordion-content.directive";
import { AccordionTitle } from "./directives/accordion-title.directive";
import { AccordionHeader } from "./directives/accordion-header.directive";
@NgModule({
declarations: [
AccordionComponent,
AccordionItem,
AccordionContent,
AccordionTitle,
AccordionHeader
],
imports: [CommonModule],
exports: [
AccordionComponent,
AccordionItem,
AccordionContent,
AccordionTitle,
AccordionHeader
]
})
export class AccordionModule {}
그들 중 대다수가 선택기로 사용되고 논리가 없기 때문에 우리는 우선 명령부터 시작한다.이 명령을 놓은 숙주 요소의 템플릿 인용에 접근할 수 있도록 TemplateRef
을 주입합니다.내용 명령
@Directive({
selector: "[accordionContent]"
})
export class AccordionContent {
constructor(public templateRef: TemplateRef<any>) {}
}
표제 명령
@Directive({
selector: "[accordionHeader]"
})
export class AccordionHeader {
constructor(public templateRef: TemplateRef<any>) {}
}
표제 명령
@Directive({
selector: "[accordionTitle]"
})
export class AccordionTitle {
constructor(public templateRef: TemplateRef<any>) {}
}
프로젝트 명령
@Directive({
selector: "accordion-item"
})
export class AccordionItem {
@Input() title = "";
@Input() disabled = false;
@ContentChild(AccordionContent) content: AccordionContent;
@ContentChild(AccordionTitle) customTitle: AccordionTitle;
@ContentChild(AccordionHeader) customHeader: AccordionHeader;
}
141560, 우리는 사용자를 위해 104790의 데이터를 설정했다.우리는 @Input()
(ref) 장식기를 사용하여 내용, 제목과 제목을 인용했다.다음은 템플릿에서 제목, 컨텐트 및 제목이 전달되는 방법입니다.
<accordion-item>
<ng-template accordionHeader>ng-template>
<ng-template accordionTitle>ng-template>
<ng-template accordionContent>ng-template>
</accordion-item>
기본 설정이 완료되면 주요 구성 요소는 @ContentChild()
또는 모 구성 요소입니다.아코디언 부품
우리는 기본적으로 확장항을 관리하기 위해 하나의 상태만 관리할 수 있다.
@Component({
selector: "accordion",
templateUrl: "./accordion.component.html",
styleUrls: ["./accordion.component.css"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AccordionComponent {
expanded = new Set<number>();
/**
* Decides if the single item will be open at once or not.
* In collapsing mode, toggling one would collapse others
*/
@Input() collapsing = true;
@ContentChildren(AccordionItem) items: QueryList<AccordionItem>;
/**
* Make the toggle function available to be called from
* outside.
* @param index - Index of the accordion item
*/
getToggleState = (index: number) => {
return this.toggleState.bind(this, index);
};
toggleState = (index: number) => {
if (this.expanded.has(index)) {
this.expanded.delete(index);
} else {
if (this.collapsing) {
this.expanded.clear();
}
this.expanded.add(index);
}
};
}
Set은 현재 확장된 아코디언 프로젝트의 상태를 유지하는 데 사용됩니다.집합은 서로 다른 값을 보증한다. @ContentChildren(AccordionItem) items: QueryList<AccordionItem>;
이것은 보기에서 내용을 교체하고 표시할 수 있는 템플릿의 아코디언 프로젝트를 제공합니다.AccordionComponent
을 입력하여 아코디언 동작을 정의한 사용자입니다.그것은 아코디언이 펼쳐질 때 다른 항목을 닫을지 여부를 알려준다.collapsing
이라는 함수를 추가하여 기본적으로 항목의 상태를 전환할 수 있습니다.이 항목의 인덱스를 전달합니다. 이 인덱스는 이 항목을 검사하고 펼치거나 접을 것입니다.toggleState
함수는 특수한 함수입니다. 잠시 후에 토론하겠습니다.아코디언 모듈 템플릿
이제 이 모든 것이 어떻게 안배되었는지 봅시다.
<section class="accordion">
<div *ngFor="let item of items;index as i"
class="accordion__item" [class.disabled]="item.disabled" [class.active]="expanded.has(i)">
<ng-container
[ngTemplateOutlet]="(item?.customHeader?.templateRef || defaultHeader)"
[ngTemplateOutletContext]="{$implicit: item, index: i, toggle: getToggleState(i)}"></ng-container>
<div class="accordion__content" [class.expanded]="expanded.has(i)" [@contentExpansion]="expanded.has(i) ? 'expanded':'collapsed'">
<ng-container *ngTemplateOutlet="item?.content?.templateRef"></ng-container>
</div>
</div>
</section>
<ng-template #defaultHeader let-item let-index="index">
<header class="accordion__header"
(click)="item.disabled ? {} :toggleState(index)">
<ng-container *ngTemplateOutlet="item?.customTitle?.templateRef || defaultTitle"></ng-container>
<button class="accordion__toggle-btn" [disabled]="item.disabled">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path d="M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z"/>
</svg>
</button>
</header>
<ng-template #defaultTitle>
<p class="accordion__title">{{item?.title}}</p>
</ng-template>
</ng-template>
우리는 단지 getToggleState
수조(Querylist)를 교체했을 뿐이다. 이것은 기본적으로 items
구성 요소에서 전달된 accordion-items
의 목록이다.내용 투영
<ng-container
[ngTemplateOutlet]="(item?.customHeader?.templateRef || defaultHeader)"
[ngTemplateOutletContext]="{$implicit: item, index: i, toggle: getToggleState(i)}">
</ng-container>
사용자가 사용자 정의 제목을 제공하면 이 템플릿이나 accordion
을 사용합니다.우리는 defaultHeader
(ref)이라는 물건을 사용하여 템플릿을 보기에 투영한다.ngTemplateOutlet
은 일부 정보를 템플릿에 전달하는 데 사용됩니다.Dell은 다음과 같은 이점을 제공합니다.ngTemplateOutletContext
- 현재 아코디언 종목.item
- 아코디언 항목의 인덱스(전환 시 필요).index
- 아코디언 프로젝트를 전환할 수 있는 함수toggle
속성은 현재 상하문과 그에 연결된 색인을 가진 함수입니다.따라서, 인덱스 값을 함수에 전달할 필요가 없이, 이 특정 항목은 언제 호출되든지 자동으로 전환됩니다.14174790(우리도 정확한 원인으로 함수 14156104790을 호출할 수 있다).
getToggleState = (index: number) => {
return this.toggleState.bind(this, index);
};
참고: 템플릿에서 메서드를 사용하는 것이 걱정되는 경우 코드를 보다 좋게 만드는 두 가지 방법이 있습니다.1. 기억 전환 방법
import { memoize } from 'lodash-es';
getToggleState = memoize((index: number) => {
console.log('Called');
return this.toggleState.bind(this, index);
})
2. 파이핑 사용자정의 사용
@Pipe({
name:'getToggleFunction'
})
export class TogglePipe implements PipeTransform{
transform(i: number, toggleFn: Function){
return () => toggleFn(i);
}
}
템플릿을 원하는 대로 변경합니다.<ng-container
[ngTemplateOutlet]="(item?.customHeader?.templateRef || defaultHeader)"
[ngTemplateOutletContext]="{$implicit: item, index: i, toggle: i | getToggleFunction: toggleState}">
</ng-container>
사용법
다음은
arrow
을 사용하는 방법입니다.<ng-template #defaultHeader let-item let-index="index"></ng-template>
toggleState
을 호출할 때, 이것은 우리가 추가한 은식 속성 (this
) 을 가리킨다.이것은 사용자가 원하는 속성을 지정하지 않았을 때 getToggleState
값을 사용한다는 것을 의미할 뿐이다. (어떻게 ngTemplateOutletContext
을 조회하는지 참조)let-item
을 추가함으로써, 우리는 index 속성을 {$implicit: item}
이라는 변수에 분배합니다.이렇게 하면 템플릿에서 변수를 사용할 수 있습니다.마지막으로, 이 구성 요소를 어떻게 사용하는지 봅시다.우선
default
은 먼저 수입한 다음에 사용해야 한다.다음은 이 구성 요소를 사용하는 모든 다른 방법입니다.
기본용법
<accordion [collapsing]="collapsing">
<accordion-item title="Super simple Accordion">
<ng-template accordionContent>
<div class="p-4">
A simple and customizable accordion component.
</div>
</ng-template>
</accordion-item>
</accordion>
사용자 정의 제목
<accordion [collapsing]="collapsing">
<accordion-item>
<ng-template accordionTitle>
<div class="flex space-x-2">
<p>Custom Title</p>
</div>
</ng-template>
<ng-template accordionContent>
<div class="p-4">
This is a simple implementation where title part is custom.
</div>
</ng-template>
</accordion-item>
</accordion>
사용자 정의 제목 포함
<accordion [collapsing]="collapsing">
<accordion-item title="Super simple Accordion">
<ng-template accordionHeader let-toggle="toggle">
<div class="flex items-center justify-between px-4 h-12 bg-purple-200">
<p> Custom Header <span>(with custom toggle button)</span><p>
<div class="flex space-x-2">
<button (click)="toggle()">Toggle</button>
</div>
</div>
</ng-template>
<ng-template accordionContent>
<div class="p-4">
This is a <strong>complete custom header</strong> implementation.
</div>
</ng-template>
</accordion-item>
</accordion>
먼저 index
함수를 정의한 다음 버튼 let-index="index"
에서 이 함수를 사용하는 방법을 보십시오이것은angular에서 간단하지만 사용자 정의 아코디언 구성 요소를 만드는 방법입니다.
보상:애니메이션
사용자가 아코디언 항목을 전환할 때 내용 애니메이션을 설정하는 각도 애니메이션을 추가했습니다.
이를 위해, 두 가지만 추가하면 된다.먼저 애니메이션을
index
decorator(ref)에서 정의해야 합니다.@Component({
// --- removed for brevity
animations: [
trigger('contentExpansion', [
state('expanded', style({height: '*', opacity: 1, visibility: 'visible'})),
state('collapsed', style({height: '0px', opacity: 0, visibility: 'hidden'})),
transition('expanded <=> collapsed',
animate('200ms cubic-bezier(.37,1.04,.68,.98)')),
])
]
})
export class AccordionComponent {}
그런 다음 템플릿에서 다음을 수행합니다.<div class="accordion__content" [@contentExpansion]="expanded.has(i) ? 'expanded':'collapsed'">
<ng-container *ngTemplateOutlet="item?.content?.templateRef"></ng-container>
</div>
애니메이션 트리거를 AccordionModule
에 추가하고 확장 조건에 따라 상태를 전달합니다.이것은 판넬을 전환할 때 우리에게 매끄러운 애니메이션을 제공했다.아코디언에 필요한 모든 스타일은
toggle
파일에 있습니다.TailwindCSS는 기본 응용 프로그램의 스타일만 설정하는 데 사용됩니다.코드 및 데모
데모: https://ssscp.csb.app
코드: https://codesandbox.io/s/ng-accordion-ssscp
파이핑 코드: https://codesandbox.io/s/ng-accordion-optimized-49bxr
연락 주세요.
보안 유지❤️
Reference
이 문제에 관하여(간단하지만 맞춤형 아코디언 부품), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/angular/a-simple-but-customizable-accordion-component-in-angular-ck0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)