angular - Angular 6 循环依赖逻辑解决方案
问题描述
我有逻辑问题。我需要将在服务中导入并在我需要该服务的组件中并行的组件。以下错误:
Circular dependency: dist\services\modal.service.js -> dist\components\modal\modal.component.js -> dist\services\modal.service.js
这是解决这种情况的最佳方法。我最好的解决方案是使用第三个服务,它会以某种方式注入这两个文件。在服务中包含组件的原因是在其他组件中使用它。
服务.ts
import { ComponentFactoryResolver, EmbeddedViewRef, ApplicationRef, ComponentRef, Injectable, Injector
} from '@angular/core';
import { ModalComponent } from '../components/modal/modal.component';
@Injectable({
providedIn: 'root'
})
export class ModalService {
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private appRef: ApplicationRef,
private injector: Injector
){}
private data = {};
private last;
open(component: any, obj:any = {}) {
if(!obj.id) obj.id = new Date().getTime();
// Create a component reference from the component
const componentRef = this.componentFactoryResolver
.resolveComponentFactory(component)
.create(this.injector);
// Attach component to the appRef so that it's inside the ng component tree
this.appRef.attachView(componentRef.hostView)
// Get DOM element from component
const contentElem = (componentRef.hostView as EmbeddedViewRef<any>)
.rootNodes[0] as HTMLElement;
// Create a component reference from the component
let componentRefer = this.componentFactoryResolver
.resolveComponentFactory(ModalComponent)
.create(this.injector);
// Attach component to the appRef so that it's inside the ng component tree
this.appRef.attachView(componentRefer.hostView);
// Get DOM element from component
const domElem = (componentRefer.hostView as EmbeddedViewRef<any>)
.rootNodes[0] as HTMLElement;
// Append DOM element to the body
document.body.appendChild(domElem);
// Append DcontentElemOM element to the body
domElem.querySelector("#modalHoster").appendChild(contentElem);
// Wait some time and remove it from the component tree and from the DOM
this.data[obj.id]={
componentRefer: componentRefer,
appRef: this.appRef
}
this.last=obj;
return obj.id;
}
pull(){
return this.last;
}
close(id){
this.data[id].appRef.detachView(this.data[id].componentRefer.hostView);
}
}
组件.ts
import { Component, OnInit } from '@angular/core';
import { ModalService } from '../../services/modal.service';
@Component({
selector: 'modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.scss']
})
export class ModalComponent implements OnInit {
close(){
this.mod.close(this.id);
}
constructor(private mod: ModalService){}
ngOnInit() {
let obj=this.mod.pull();
for(let key in obj){
this[key]=obj[key];
}
}
}
可能是我的逻辑错了,这就是我要问的。这两个服务和组件在模块内部,而不是应用程序。App 仅使用服务,组件不可访问。服务需要一段 html/css/ts 代码作为应用程序提供的一段 html/css/ts 代码的容器。
解决方案
您的逻辑在这里并没有真正错误,但您可以轻松避免循环依赖。
您肯定需要服务中的组件来创建新实例。但是,您实际上并不需要模态中的服务。
您可以做的是在您的模态中添加一个可观察的主题。当您实例化您的模式时,您在服务中订阅此主题以从容器中删除对话框。
这是一个简单的代码示例:)
在您的模态组件中:
private modalClose: Subject<any> = new Subject();
onModalClose(): Observable<any> {
return this.modalClose.asObservable();
}
close() { // Will be generally called from the UI (close button for example)
this.modalClose.next();
this.modalClose.complete();
}
在您的服务中:
componentRefer.instance.onModalClose().subscribe( () => {
// Here you close your modal :D
});
了解更多信息 :
在这里你可以找到我自己的“模态/对话框”。
https://github.com/xrobert35/asi-ngtools/tree/master/src/components/asi-dialog
要实例化一个对话框,您必须使用该服务。该服务管理一个可以有“许多”对话框的“容器”。使用相同的技术,我没有循环依赖。
在这里您可以找到该组件的工作示例:https ://ng-tools.asi.fr/views/showroom/asi-ngtools/components/asi-dialog
推荐阅读
- reactjs - 无法将 web3 添加到 React 项目
- facebook - 从 fb 营销 API 检索字段“转化”
- mongodb - 身份验证失败。MongoDB
- c# - NET 5 中的 PropertyGrid 问题
- reactjs - SAD PANDA:TypeError:获取失败
- python - 在 DataFrame 中查找
- fancybox - Fancybox - 当自动启动为真时,全屏不退出
- dart - Dart HashMap 初始值
- reactjs - 无法为测试获取 TreeView 图标和 IconButton
- android - 当 RecyclerView 项目出现在 Android 的 ViewPager2 中时,如何延迟加载它?