为什么要从一个模块导出组件并在另一个模块组件中使用

问题描述 投票:0回答:3

我已经为此努力了很长时间。然而,我最终放弃并寻求社区的支持。预先感谢您的帮助!

我有使用网页组件的网络项目模块。我正在 Webprojects 模块中导入对象模块(具有导航栏组件和 ComponentLoaderDirective)。

&我正在尝试将 navbar.html 的内容加载到webpage.component.html

为什么 Angular 强迫我在 weboage.components.ts 中再次导入 NavbarComponent 和 ComponentLoaderDirective?如果没有相同的我会得到以下错误: 找不到名称“导航栏组件”。 找不到名称“ComponentLoaderDirective”。

我想我在这里遗漏了一些东西。只是无法找到丢失的东西。

webprojects.module.ts

import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { Global } from '../../../class.global'; //Global Class Contains the Global Variables & Functions Being Used Throughout the Project.
import { StartupService } from 'src/app/services/shared/startup.service'; //StartupService is Used to Get the Project, Page, Object & Elements on Page Load.
import { ObjectsModule } from './objects/objects.module';
import { WebpageComponent } from './webpage/webpage.component'; //WebProjectsModule Uses WebpageComponent as the View (webpage.component.html) & Controller (webpage.component.html).

@NgModule({
  declarations: [WebpageComponent], //WebProject Module Uses the Webpage Component
  imports: [HttpClientModule, ObjectsModule],
  exports: [], //Webprojects Module Exports the Webpage Component to the App Module & Other Modules Using the WebProjects Module
  providers: [StartupService, Global] //StartupService, GlobalClass are Required for the WebProjects Module to Work.  
})
export class WebProjectsModule {}

网页.component.ts

//Webpage Component is the First Component to be loaded Under the Webprojects Module.
import { Component, ViewChild, OnInit } from '@angular/core';
import { Global } from '../../../../class.global'; //Global Class Contains the Global Variables & Functions Being Used Throughout the Project.
import { Error } from '../../../../services/shared/error' //Error Class is Used to Display Errors
import { StartupService } from '../../../../services/shared/startup.service'; //StartupService is Required to Load the Project, Page, Object & Elements.
import { Project } from '../../../../services/projects/webprojects/project'; //Project Model is Required to Constrain the Type of Data Being Received from the Startup Service getProjects().
import { Projectpage } from '../../../../services/projects/webprojects/projectpage'; //Project Page Model is Required to Constrain the Type of Data Being Received from the Startup Service getProjectPage().
import { Pageobject } from '../../../../services/projects/webprojects/pageobject'; //Page Object Model is Required to Constrain the Type of Data Being Received from the Statup Service getPageObjects().
import { Property } from '../../../../services/projects/webprojects/property'; //Property Object Model is Required to Constrain the Type of Property Array Being Created for Objects & Elements.
import { SEOService } from '../../../../services/shared/seo.service'; //SEO Service is Used to Display the Page Title, Description, Other SEO Related Content on the Page.
import { ComponentLoaderDirective } from '../../../../services/shared/component-loader.directive';
import { NavbarComponent } from '../objects/navbar/navbar.component';

@Component({
  selector: 'app-webpage',
  templateUrl: './webpage.component.html',
  styleUrls: ['./webpage.component.scss']
})
export class WebpageComponent implements OnInit {
  @ViewChild(ComponentLoaderDirective, {static: true}) pageObjectLoader!: ComponentLoaderDirective;

  responseProject: Project[] = []; //Variable of Type Project Array Used to Store the Array of Projects Received from the Startup Service getProjects().
  project: any = {}; //Variable of Type Any Used to Store the Parameters of the Current Project being Loaded. Initializing with Empty Object.
  projectId: number = 0; //Variable of Type Number Used to Store the Id of the Current Project being Loaded. Initilizing with 0.
  projectType: string = 'web'; //Variable of Type String Used to Store the Type of the Current Project being Loaded. Initializing with web.
  responseProjectPage: Projectpage[] = []; //Variable of Type Projectpage Array Used to Store the Object of Projectpage Received from the Statup Service getProjectPage().
  projectPage: any = {}; //Aggregate of Type Object Used to Store the Parameters of Project Page, Project & Page. Initializing with Empty Object.
  projectPageProperties: Property[] = []; //Variable of Type Property[] Used to Store Array of Properties of Project Page.
  page: any = {}; //Variable of Type Any Used to Store the Parameters of the Current Page being Loaded.
  pageTitle: string = ''; //Variable of Type String Used to Store the Title of the Current Page being Loaded.
  pageDescription: string = ''; //Variable of Type String Used to Store the Description of the Current Page being Loaded.
  pageProperties: Property[] = []; //Variable of Type Property Used to Store the Properties of the Page being Loaded.
  pageType: string = 'home'; //Variable of Type String Used to Store the Type of Current Page being Loaded. Initializing with home by default to be loaded. Unless Overwritten by the Route.
  pageObjects: Pageobject[] = []; //Variable of Type Any Used to Store the Page & Object Parameters Relevant to the Page Being Loaded. Initializing with Empty Object.
  pageObjectProperties: Property[] = []; //Variable of Type Property[] Used to Store the Array of Page Object Properties.
  object: any = {}; //Variable of Type Any Used to Store the Object Relevant to the Page Being Loaded. Initializing with Empty Object.
  objectProperties: Property[] = []; //Variable of Type Property[] Used to Store the Array of Object Properties.
  properties: Property[] = []; //Variable of Type Property[] Used to Store Array of Properties.
  active: boolean = true; //Initializing with true. All the Requests to Get the Projects, ProjectPages & PageObjects are with Active = true.
  global = new Global();
  error = new Error();

  constructor(private startupService: StartupService, private seoService: SEOService) {};

  async ngOnInit(){
    try{
      this.responseProject = await this.startupService.getProjects(this.projectType,this.active).toPromise();  
      var i = this.responseProject.length;
      while(i--){
        if(this.responseProject[i].tags.indexOf(window.location.href) == -1){ //Using window.location.href to Get the Url Which Was Loaded & Get the Project Accordingly.
          this.responseProject.splice(i, 1); //Removes the Project from the Array if it is Not Relevant to the Current Project.
        }
      };

      if(this.responseProject.length > 0){ //Checks if Atleast 1 Project is Received.
        this.project = this.responseProject[0]; //Storing the Relevant Project in the Project Variable
        this.projectId = this.project.nid; //Storing the Relevant Project Id in the projectId Variable.

        this.responseProjectPage = await this.startupService.getProjectPage(this.projectId, this.pageType, this.active).toPromise();
        //Use the getPage() in StartupService to Get the Home Page of the Relevant Project Being Loaded.
        if(Object.keys(this.responseProjectPage).length === 1){ //Checks if the Array Received is Not Empty.          
          this.projectPage = this.responseProjectPage[0]; //Aggregate Object Received from the Database is Stored in projectPage Variable.
          this.projectPageProperties = this.projectPage.properties; //Project Page Properties which are a Part of the Aggregate Received is Separately Stored in projectPageProperties Variable.

          this.page = this.projectPage.page; //Page Object which is Part of the Aggregate Received is Separately Stored in page Variable.
          this.pageProperties = this.page.properties; //Page Properties which are a Part of the Page Object Received are Separately Stored in pageProperties Variable.
          
          //We Pick All the Properties from projectPageProperties & the Remaining Properties from pageProperties which are Not a Part of projectPageProperties.
          var namesToFilter = new Set(this.projectPageProperties.map(d => d.name)); //We Get All the Names in the projectPageProperties Array and Store them in namesToFilter Array.
          this.properties = [...this.projectPageProperties, ...this.pageProperties.filter(d => !namesToFilter.has(d.name))]; //We Merge Both the Arrays and Skip the Objects with Names in the namesToFilter Array.
          
          //Looping through the Properties Array to Get the Page Title & Description for the <head> Tag.
          this.properties.forEach((property: Property) => {   
            this.pageTitle = (property.name === 'pgTitle')?property.value:this.pageTitle;      
            this.pageDescription = (property.name === 'pgDescription')?property.value:this.pageDescription;
          });                
          this.seoService.updateTitle(this.pageTitle); //Using the SEO Service, We Update the <html><head><title> Tag of the Page.
          this.seoService.updateDescription(this.pageDescription); //Using the SEO SErvice, We Update the <html><head><meta = "description"> Tag is the Page.

          this.pageObjects = this.projectPage.pageobjects; //Storing the Page Objects Array in pageObjects Variable.
          if(this.pageObjects.length > 0){ //Checking if there is Atleast One Page Object.
            const viewContainerRef = this.pageObjectLoader.viewContainerRef; //We Use Instance of Component Loader Directive to Define Where to Load the Child Component.

            this.pageObjects.forEach((pageObject: Pageobject) => { //Looping through the Page Objects.
              this.pageObjectProperties = pageObject.properties; //Storing the Page Object Properties Array in pageObjectProperties Variable.              

              this.object = pageObject.object; //Storing the Object which is Part of Page Object in the object Variable.
              this.objectProperties = this.object.properties; //Storing the Properties of Object in the objectProperties Variable.

              //We Pick All the Properties from pageObjectProperties & the Remaining Properties from objectProperties which are Not a Part of pageObjectProperties.
              namesToFilter = new Set(this.pageObjectProperties.map(d => d.name)); //We Get All the Names in the pageObjectProperties Array and Store them in namesToFilter Array.
              this.properties = [...this.pageObjectProperties, ...this.objectProperties.filter(d => !namesToFilter.has(d.name))]; //We Merge Both the Arrays and Skip the Objects with Names in the namesToFilter Array.

              switch(this.object.path){ //Based on the Path of Object We Load the Respective Component.
                case 'NavbarComponent':{ //NavbarComponent Relates with the Object Type of navbar.
                  const componentRef = viewContainerRef.createComponent<any>(NavbarComponent);
                  componentRef.instance.properties = this.properties;
                  break;
                }
              };
            });
          } else { //Throw Error if No Page Objects Were Received.
            this.error.display('Error Loading Project in webpage.component. Unable to Fetch Page Objects Data...');
          };          
        } else { //Throw Error if Query Ran Succcessfully. However, No Project Page Was Received.
          this.error.display('Error Loading Project in webpage.component. Unable to Fetch Project Page Data...');
        };
      } else { //Throw Error if Query Ran Succcessfully. However, No Projects Were Received.
        this.error.display('Error Loading Project in webpage.component. Unable to Fetch Projects Data...');    
      };
    } catch(error){
      this.error.display('Error Loading Project in webpage.component...', error);
    };
  };
};

网页.component.html

<ng-template pageObjectLoader></ng-template>
<div>Webpage Works!</div>

objects.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NavbarComponent } from './navbar/navbar.component';
import { ComponentLoaderDirective } from '../../../../services/shared/component-loader.directive';
import { MaterialModule } from '../material/material.module';

let components = [NavbarComponent, ComponentLoaderDirective];

@NgModule({
  declarations: [components],
  imports: [CommonModule, MaterialModule],
  exports: [components]
})
export class ObjectsModule {}

navbar.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { Property } from '../../../../../services/projects/webprojects/property';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit {
  @Input() properties: Property[] = []; //Properties of Navbar Component
  @Input() elements: any; //Elements of Navbar Component

  class: string = '';    
  
  ngOnInit(): void {
    this.properties.forEach((property) => {
      this.class += (property.type = 'class')?(this.class == '')?property.value:' ' + property.value:'';
    });
  };
}

navbar.component.html

<mat-toolbar [ngClass]="class">
    <span>Yellow Pages & Classifieds | ypandc.com</span>
</mat-toolbar>
angular typescript angular-directive angular-components angular-module
3个回答
1
投票

请阅读 ngmodule-vs-jsmodule 文章,它解释了 jsModules 和 ngModules 之间的区别。它们是两个不同的东西:

JavaScript 模块和 NgModules 可以帮助您模块化代码,但它们有很大不同。 Angular 应用程序依赖于这两种模块。

  1. ngModule 有一个“import”属性,可以导入其他模块,这些模块的导出类是此 NgModule 中声明的组件模板所需要的。

  2. jsModule 应该声明语法,以便在另一个 .ts 文件中使用 js 模块。

导出/导入 ngModule 属性是必要的,以便声明哪些类可以在其他模块中导入,而 component.ts 中的第二个“导入”只是用于访问文件中对象的打字稿语法。


0
投票

根据我对模块如何工作的理解,您还需要导出 NavbarComponent 才能在使用 ObjectsModule

的组件中访问它
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NavbarComponent } from './navbar/navbar.component';
import { ComponentLoaderDirective } from '../../../../services/shared/component-loader.directive';
import { MaterialModule } from '../material/material.module';

let components = [NavbarComponent, ComponentLoaderDirective];

@NgModule({
  declarations: [components],
  imports: [ CommonModule, MaterialModule ],
  exports: [ components, NavbarComponent ]
})
export class ObjectsModule {}

-1
投票

这很简单,不用担心。您需要使用SCAM(单组件角度模块)。下面是一个适合您的示例:

创建您的模块,仅导出一个组件! - 这非常重要

@NgModule({
  declarations: [ModuleAComponent],
  exports: [ModuleAComponent],
  imports: [
    ButtonModule // etc
  ],
})
export class ModuleA {}

在 ModuleB 中导入 ModuleA - 看,很简单

@NgModule({
  declarations: [ModuleBComponent],
  exports: [ModuleBComponent],
  imports: [
    ModuleB
  ],
})
export class ModuleB {}
© www.soinside.com 2019 - 2024. All rights reserved.