代码之家  ›  专栏  ›  技术社区  ›  Honchar Denys

角6循环依赖逻辑解决方案

  •  1
  • Honchar Denys  · 技术社区  · 7 年前

    我有逻辑问题。我需要一个组件,它将被导入到一个服务中,并在这个组件中并行,我需要这个服务。错误如下: Circular dependency: dist\services\modal.service.js -> dist\components\modal\modal.component.js -> dist\services\modal.service.js

    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];
            }
        }
    }
    

    可能是我的逻辑错了,这就是我要问的。这两个服务和组件在模块内部,而不是应用程序。应用程序仅使用服务,组件不可访问。服务需要一段html/css/ts代码作为应用程序提供的html/css/ts代码的容器。

    1 回复  |  直到 7 年前
        1
  •  3
  •   xrobert35    7 年前

    您的逻辑在这里并不是真的错,但是您可以很容易地避免循环依赖。

    你能做的就是在你的模态中添加一个可观察的主题。当您实例您的模态时,您在您的服务中订阅这个主题,以便从is容器中删除对话框。

    下面是一个简单的代码示例:)

    在模态组件中:

    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

    推荐文章