이번에는 Angular에서 동적 로딩 컴포넌트 방식을 사용하여 Dialog를 구현하는 단계에 대해 자세히 설명하겠습니다. Angular에서 동적 로딩 컴포넌트 방식을 사용하여 Dialog를 구현하는 Notes는 무엇입니까? 사례를 살펴보겠습니다.
인터넷의 기사와 튜토리얼은 기본적으로 구성 요소가 로드되면 끝납니다! 다 쓴? ! 그리고 대화상자는 하나만 있을 수 있는데, 또 다른 대화상자를 열려면 현재 열려 있는 대화상자를 먼저 파기해야 합니다. 이제 대화 상자 구성 요소를 사용할 수 있습니다.
대화 상자 구성 요소의 목표: 여러 개의 대화 상자가 동시에 존재할 수 있으며 지정된 대화 상자가 파괴된 후에는 구성 요소가 HTML에 남아 있지 않습니다. Angular4.0 버전 ComponentFactoryResolver가 구현되기 전에 사용되었던 컴포넌트를 동적으로 로드하는 방법이 두 가지 있습니다. 4.0 이후에는 ngComponentOutlet을 사용하여 구현할 수 있습니다.
ComponentFactoryResolver 먼저 ViewChild, ViewChildren, ElementRef, ViewContainerRef, ViewRef, ComponentRef 및 ComponentFactoryResolver 간의 관계를 정리하겠습니다.
ViewChild 및 ViewChildrenViewChild는 템플릿 참조
변수를 통해 Angular Dom추상 클래스를 얻는 데 사용됩니다. ( #) 또는 지시문(지시문). ViewChild는 ElementRef 또는 ViewContainerRef를 사용하여 캡슐화할 수 있습니다. @ViewChild('customerRef') customerRef:ElementRef;
@ViewChildren(ChildDirective) viewChildren: QueryList<ChildDirective>;
ViewChild는 ElementRef 또는 ViewContainerRef를 사용하여 캡슐화할 수 있습니다. 그렇다면 ElementRef와 ViewContainerRef의 차이점은 무엇인가요?
ElementRef를 사용하여 캡슐화한 다음 .nativeElement를 사용하여 기본 Dom 요소를 가져옵니다.
console.log(this.customerRef.nativeElement.outerHTML);
ViewContainerRef: 뷰를 생성하는 방법과 뷰를 작동하기 위한 API를 포함하는 뷰의 컨테이너(컴포넌트와 템플릿이 공동으로) 뷰를 정의합니다.) API는 ComponentRef와 ViewRef를 반환하는데, 이 두 가지는 무엇입니까?
// 使用ViewContainetRef时,请使用read声明 @ViewChild('customerRef',{read: ViewContainerRef}) customerRef:ViewContainerRef; ··· this.customerRef.createComponent(componentFactory) // componentFactory之后会提到
ViewRef는 가장 작은 UI 단위입니다. ViewContainerRef API가 작동하여 ViewRef를 얻습니다.
ComponentRef: 호스트 뷰(컴포넌트 인스턴스 뷰)는 ViewContainerRef를 통해 컴포넌트 뷰에 대한 참조를 생성하고 해당 컴포넌트의 뷰를 얻을 수 있습니다. 정보 및 구성요소 메소드 호출
ComponentFactoryResolverComponentRef를 얻으려면 ViewContainer의 createComponent 메소드를 호출해야 합니다. 이 메소드는 ComponentFactoryResolver
constructor( private componentFactoryResolver:ComponentFactoryResolver ) { } viewInit(){ componentFactory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent); // 获取对组件视图的引用,到这一步就已经完成了组件的动态加载 componentRef = this.customerRef.createComponent(componentFactory); // 调用载入的组件的方法 componentRef.instance.dialogInit(component); }
특정 구현에서 생성된 매개변수를 전달해야 합니다. componentfactory, componentRef; @ViewChild('customerRef',{read: ViewContainerRef}) customerRef:ViewContainerRef;
constructor(
private componentFactoryResolver:ComponentFactoryResolver
) { }
viewInit(){
// DialogComponent:你想要动态载入的组件,customerRef:动态组件存放的容器
componentFactory =
this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
componentRef = this.customerRef.createComponent(componentFactory);
}
cheieve ngcomponentOutlet
ngcomponentOutlet를 통한 동적로드는 코드의 양을 크게 줄입니다. Dialog.comComponent.html<ng-container *ngComponentOutlet="componentName"></ng-container>
dialogInit(component){ this.componentName = component; };
대화 상자 구현
구현 아이디어는 다음과 같습니다. 먼저 다른 구성 요소를 호스팅할 대화 상자 구성 요소를 만들고, 대화 상자에 대한 마스크와 애니메이션을 만들고, 대화 상자의 생성과 소멸을 제어하는 서비스를 설정합니다. 그러나 서비스는 대화 상자만 생성합니다. 대화 상자 구성 요소는 여전히 대화 상자 구성 요소에서 생성되어야 합니다. 1. 먼저 루트 구성 요소의 viewContainerRef를 가져오기 위해 공용 서비스를 작성합니다. 루트 구성 요소의 viewContainerRef를 가져오기 위해 ApplicationRef를 시도했습니다. 구성 요소가 실패하여 서비스로 작성했습니다.)
gerRootNode(...rootNodeViewContainerRef){ if(rootNode){ return rootNode; }else { rootNode = rootNodeViewContainerRef[0]; }; } // 然后再根组件.ts内调用 this.fn.gerRootNode(this.viewcontainerRef);
2.Dialog.service.ts를 만들고, 열기 및 닫기의 세 가지 메서드를 정의하고, ViewContainerRef를 사용하여 대화 상자 구성 요소를 생성하기 전에 ComponentFactoryReslover를 호출하고 전달해야 합니다.
let componentFactory; let componentRef; @Injectable() export class DialogService { constructor( private componentFactoryResolver:ComponentFactoryResolver private fn:FnService ) { } open(component){ componentFactory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent); // 这里的获取的是ComponentRef containerRef = this.fn.gerRootNode().createComponent(componentFactory); // 将containerRef存储下来,以便之后的销毁 containerRefArray.push(containerRef); // 调用了组件内的初始化方法,后面会提到 return containerRef.instance.dialogInit(component,containerRef); } // 这里有两种情况,一种是在当前组件和dialog组件关闭调用的,因为有返回值所以可以关闭指定的dialog;还有一种是在插入到dialog组件内的组件调用的,因为不知道父组件的信息,所以默认关闭最后一个dialog close(_containerRef=null){ if( _containerRef ){ return _containerRef.containerRef.instance.dialogDestory(); }else{ containerRefArray.splice(-1,1)[0].instance.dialogDestory(); } } }
3.Dialog.comComponent.ts의 DialogComponent, 여기서는 ngComponentOutlet을 사용하여 구현합니다(ngComponentOutlet은 아래에 언급되어 있으므로 게으름을 위해 직접 사용합니다) 4、这里还创建了一个 DialogRef 的类,用来处理 dialog 关闭后的回调,这样就可以使用 XX.afterClose().subscribe() 来创建回调的方法了 创建和销毁dialog 相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章! 推荐阅读:let containerRef,dialogRef = new DialogRef();
export class DialogComponent implements OnInit {
componentName;
constructor(
private fn:FnService
) { }
dialogInit( _component, _containerRef){
this.componentName = _component;
containerRef = _containerRef;
dialogRef['containerRef'] = containerRef;
return dialogRef;
};
dialogDestory(){
let rootNode = this.fn.gerRootNode();
// 等待动画结束再移除
setTimeout(()=>{
// 这里用到了 viewContainerRef 里的indexOf 和 remove 方法
rootNode.remove(rootNode.indexOf(containerRef.hostView));
},400);
dialogRef.close();
return true;
};
}
@Injectable()
export class DialogRef{
public afterClose$ = new Subject();
constructor(){}
close(){
this.afterClose$.next();
this.afterClose$.complete();
}
afterClose(){
return this.afterClose$.asObservable();
}
}
// 创建
let _viewRef = this.dialogService.open(DialogTestComponent);
_viewRef.afterClose().subscribe(()=>{
console.log('hi');
});
// 销毁
this.dialogService.close()
위 내용은 Angular는 동적 로딩 구성 요소 방법을 사용하여 대화 상자 단계에 대한 자세한 설명을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!