Угловой выпуск 5 нг-контента

У меня странная проблема, когда я реализую ng-контент между двумя компонентами в Angular 5.

Это мой первый компонент FooterComponent

<div class="footer">
  <ng-content select="footer"></ng-content>
</div>

И footer.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.css']
})
export class FooterComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

И это второй компонент AboutComponent

<app-footer>
  <footer>
   this is my footer
  </footer>
</app-footer>

Также этот app-module.ts в первой попытке и во второй попытке я импортирую about.module.ts или footer.module.ts вместо AboutComponent и FooterComponent.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { FooterComponent } from './footer/footer.component';

@NgModule({
  declarations: [
    AppComponent,
    AboutComponent,
    FooterComponent
  ],
  imports: [
    BrowserModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class AppModule { }

А в app.component.html есть только метка роутер-розетка

<router-outlet></router-outlet>

Итак, у меня есть две проблемы, во-первых, когда я запускаю Angular с помощью командной строки ng serve, я не вижу никакого вывода. Второй и важный момент - когда я запускаю командную строку ng test, я вижу эту ошибку...

AboutComponent should create
  Failed: Template parse errors:
  'app-footer' is not a known element:
  1. If 'app-footer' is an Angular component, then verify that it is part of 
     this module.
  2. If 'app-footer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to 
     the '@NgModule.schemas' of this component to suppress this message. ("
     [ERROR ->]<app-footer>
     <footer>
     this is my footer
     "): ng:///DynamicTestModule/AboutComponent.html@0:0

Поэтому я пробовал много решений, как

  1. Создайте about.module.ts и импортируйте CUSTOM_ELEMENTS_SCHEMA и попробуйте NO_ERRORS_SCHEMA. А также импортировать FooterComponent и, наконец, импортировать about.module.ts в app.module.ts

  2. Я делаю то же самое с FooterComponent.

  3. Я пытался использовать CUSTOM_ELEMENTS_SCHEMA и NO_ERRORS_SCHEMA в каждом модуле, и это дает мне тот же результат.

И этот пакет. Json

{
 "name": "ng-app",
 "version": "0.0.0",
 "license": "MIT",
 "scripts": {
   "ng": "ng",
   "start": "ng serve",
   "build": "ng build --prod",
   "test": "ng test",
   "lint": "ng lint",
   "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.5.6",
    "zone.js": "^0.8.19"
  },
  "devDependencies": {
    "@angular/cli": "~1.7.3",
    "@angular/compiler-cli": "^5.2.0",
    "@angular/language-service": "^5.2.0",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": "~2.5.3"
  }
}

Наконец этот новый Angular-Cli Project я создал.

Благодарю.

1 ответ

Решение

Первое, что вам нужно сделать, это включить RouterModule в app.module.ts. Вы пытаетесь использовать розетку роутера (<router-outlet></router-outlet>) без этого. Это не будет работать.

Обновлен app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { FooterModule } from './footer/footer.module';
import { FooterComponent } from './footer/footer.component';

@NgModule({
declarations: [
    AppComponent
],
imports: [
    BrowserModule,
    FooterModule,
    RouterModule.forRoot([
        {path: '', component: FooterComponent}
    ])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Смотрите новый импорт для RouterModule, Также после добавления RouterModule к массиву импорта я также добавил маршрут по умолчанию, который идет к FooterComponent, Мне нужно было что-то направить, это то, что я выбрал. Измените это на то, что вам нравится, когда ваше приложение прогрессирует.

Имейте в виду, что даже с этими изменениями вы ничего не увидите в браузере. Вам нужно будет добавить контент в нижний колонтитул, чтобы что-то увидеть. Я оставлю эту часть на ваше усмотрение. Если вы щелкните правой кнопкой мыши и осмотрите главную страницу во время работы ng serve, вы увидите, что элементы нижнего колонтитула отображаются (они просто не имеют никакого ценного контента, пока).

Что касается тестирования, вам нужно добавить FooterComponent в разделе объявлений в спецификации для AboutComponentвместе с импортом. Обновленная спецификация ниже.

import { FooterComponent } from './../footer/footer.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AboutComponent } from './about.component';

describe('AboutComponent', () => {
let component: AboutComponent;
let fixture: ComponentFixture<AboutComponent>;

beforeEach(async(() => {
    TestBed.configureTestingModule({
    declarations: [ AboutComponent, FooterComponent ]
    })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(AboutComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});

it('should create', () => {
    expect(component).toBeTruthy();
});
});

Так как AboutComponent хостинг FooterComponentмодульному тесту необходимо знать обо всех компонентах смеси. Это позаботится об этом.

Затем, чтобы очистить возможную ошибку, вы получите, связанные с тестированием AppComponent, вам нужно смоделировать розетку маршрутизатора для использования в спецификации. Этот код ниже.

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { Component } from '@angular/core';

describe('AppComponent', () => {
beforeEach(async(() => {
    TestBed.configureTestingModule({
    declarations: [
        AppComponent, RouterOutletStubComponent
    ],
    }).compileComponents();
}));
it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app');
}));
});


@Component({selector: 'router-outlet', template: ''})
class RouterOutletStubComponent { }

Так как вы удалили весь оригинальный HTML для AppComponent чтобы использовать его в качестве розетки маршрутизатора, мне пришлось удалить один из модульных тестов, так как он больше не был нужен.

RouterOutletStubComponent это интересная вещь здесь. Это позволяет AppComponent модульные тесты для успешного запуска. Все AppComponent На данный момент это выходной контейнер маршрутизатора.

Удачного кодирования!

Другие вопросы по тегам