Ionic3 - Ошибка разбора шаблона в пользовательском компоненте

Я работал над проектом, чтобы в курсе всех изменений в Ionic3 в последнее время. В основном он основан на демонстрационном приложении-конференции Ionic-Team .

Я все еще пытаюсь наклониться angular / ionic, большая часть приложения работала на ionic2. Ленивая загрузка общих компонент.модуль меня на некоторое время испортила. Но теперь я столкнулся с проблемой использования встроенных компонентов Ionic в моих пользовательских компонентах. Я пытаюсь создать собственный компонент, который использует ion-card для отображения информации, передаваемой в него через @Input.

Ошибка, которую он дает:

Error: Template parse errors:
'ion-card-header' is not a known element:
1. If 'ion-card-header' is an Angular component, then verify that it is part of this module.
2. If 'ion-card-header' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("


[ERROR ->]
    

{{ recipe.title }}

"): ng:///ComponentsModule/RecipeCardComponent.html@3:2 'ion-card-content' is not a known element: 1. If 'ion-card-content' is an Angular component, then verify that it is part of this module. 2. If 'ion-card-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. (" [ERROR ->]

{{ recipe.description }}

"): ng:///ComponentsModule/RecipeCardComponent.html@7:2 'ion-card' is not a known element: 1. If 'ion-card' is an Angular component, then verify that it is part of this module. 2. If 'ion-card' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. (" [ERROR ->] "): ng:///ComponentsModule/RecipeCardComponent.html@1:0

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { IonicStorageModule } from '@ionic/storage';
import { HttpModule } from '@angular/http';

import { UserDataProvider } from '../providers/user-data/user-data';
import { RecipeDataProvider } from '../providers/recipe-data/recipe-data';

import { ComponentsModule } from '../components/components.module';
import { PipesModule } from '../pipes/pipes.module';

import { MyApp } from './app.component';
import { IntroPage } from '../pages/intro/intro';
import { RecipeListPage } from '../pages/recipe-list/recipe-list';
import { FavoratesPage } from '../pages/favorates/favorates';
import { CookbooksPage } from '../pages/cookbooks/cookbooks';
import { QuickTimerPage } from '../pages/quick-timer/quick-timer';
import { ShoppingListPage } from '../pages/shopping-list/shopping-list';
import { SettingsPage } from '../pages/settings/settings';
import { AboutPage } from '../pages/about/about';
import { DatabaseProvider } from '../providers/database/database';
import { UtilitiesProvider } from '../providers/utilities/utilities';


@NgModule({
declarations: [
    MyApp,
    IntroPage,
    RecipeListPage,
    FavoratesPage,
    CookbooksPage,
    QuickTimerPage,
    ShoppingListPage,
    SettingsPage,
    AboutPage
],
imports: [
    BrowserModule,
    HttpModule,
    IonicModule.forRoot(MyApp, {}, {
    links: [
        { component: IntroPage, name: 'IntroPage', segment: 'intro' },
        { component: RecipeListPage, name: 'RecipeListPage', segment: 'recipe-list' },
        { component: FavoratesPage, name: 'FavoratesPage', segment: 'favorates' },
        { component: CookbooksPage, name: 'CookbooksPage', segment: 'cookbooks' },
        { component: QuickTimerPage, name: 'QuickTimerPage', segment: 'quick-timer' },
        { component: ShoppingListPage, name: 'ShoppingListPage', segment: 'shopping-list' },
        { component: SettingsPage, name: 'SettingsPage', segment: 'settings' },
        { component: AboutPage, name: 'AboutPage', segment: 'settings' },
    ]
    }),
    IonicStorageModule.forRoot({
    name: '__mise',
    driverOrder: ['indexeddb', 'websql', 'localstorage']
    }),
    ComponentsModule,
    PipesModule
],
bootstrap: [IonicApp],
entryComponents: [
    MyApp,
    IntroPage,
    RecipeListPage,
    FavoratesPage,
    CookbooksPage,
    QuickTimerPage,
    ShoppingListPage,
    SettingsPage,
    AboutPage
],
providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    UserDataProvider,
    RecipeDataProvider,
    DatabaseProvider,
    UtilitiesProvider
]
})
export class AppModule {}

app.component. ts

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { Storage } from '@ionic/storage';

import { UserDataProvider } from '../providers/user-data/user-data';
import { RecipeDataProvider } from '../providers/recipe-data/recipe-data';

import { IntroPage } from '../pages/intro/intro';
import { RecipeListPage } from '../pages/recipe-list/recipe-list';


export interface PageInterface {
title: string;
name: string;
component: any;
icon: string;
logsOut?: boolean;
index?: number;
tabName?: string;
tabComponent?: any;
}

@Component({
templateUrl: 'app.html'
})
export class MyApp {
@ViewChild(Nav) nav: Nav;

pages: Array<{title: string, component: any}>;

// List of pages that can be navigated to from the left menu
// the left menu only works after login
// the login page disables the left menu
appPages: PageInterface[] = [
    { title: 'intro', name: 'IntroPage', component: 'IntroPage', icon: 'help' },
    { title: 'Recipes', name: 'RecipeListPage', component: 'RecipeListPage', icon: 'list' },
    { title: 'Favorates', name: 'FavoratesPage', component: 'FavoratesPage', icon: 'star' },
    { title: 'Cookbooks', name: 'CookbooksPage', component: 'CookbooksPage', icon: 'folder' },
    { title: 'Quick timer', name: 'QuickTimerPage', component: 'QuickTimerPage', icon: 'help' },
    { title: 'Shopping list', name: 'ShoppingListPage', component: 'ShoppingListPage', icon: 'help' },
    { title: 'Settings', name: 'SettingsPage', component: 'SettingsPage', icon: 'help' },
    { title: 'About', name: 'AboutPage', component: 'AboutPage', icon: 'help' },
];

rootPage: any;

constructor(
    public platform: Platform, 
    public statusBar: StatusBar,
    public storage: Storage, 
    public splashScreen: SplashScreen,
    public userData: UserDataProvider,
    public recipeData: RecipeDataProvider
) {

    // Check if the user has already seen the tutorial
    this.storage.get('hasSeenTutorial')
    .then((hasSeenTutorial) => {
        if (hasSeenTutorial) {
        console.log('HasSeenTurorial = true');
        this.rootPage = RecipeListPage;
        } else {
        console.log('HasSeenTurorial = false');
        this.rootPage = IntroPage;
        }
        this.platformReady()
    });

    // load the recipe data
    this.recipeData.init();

}

openPage(page: PageInterface) {
    this.nav.setRoot(page.name);
}

openTutorial() {
    this.nav.setRoot(IntroPage);
}

listenToLoginEvents() {
    // this.events.subscribe('user:login', () => {
    //   this.enableMenu(true);
    // });

    // this.events.subscribe('user:signup', () => {
    //   this.enableMenu(true);
    // });

    // this.events.subscribe('user:logout', () => {
    //   this.enableMenu(false);
    // });
}

enableMenu(loggedIn: boolean) {
    // this.menu.enable(loggedIn, 'loggedInMenu');
    // this.menu.enable(!loggedIn, 'loggedOutMenu');
}

platformReady() {
    // Call any initial plugins when ready
    this.platform.ready().then(() => {
    this.splashScreen.hide();
    });
}

isActive(page: PageInterface) {
    let childNav = this.nav.getActiveChildNavs()[0];

    // Tabs are a special case because they have their own navigation
    if (childNav) {
    if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
        return 'primary';
    }
    return;
    }

    if (this.nav.getActive() && this.nav.getActive().name === page.name) {
    return 'primary';
    }
    return;
}
}

recipe-list.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

import { RecipeDataProvider } from '../../providers/recipe-data/recipe-data';
import { UserDataProvider } from '../../providers/user-data/user-data';

import { ComponentsModule } from '../../components/components.module';


@IonicPage()
@Component({
    selector: 'page-recipe-list',
    templateUrl: 'recipe-list.html',
})
export class RecipeListPage {

    recipeList: any = [];
    things: any = ["One", "Two", "Three"];

    constructor(
        public navCtrl: NavController, 
        public navParams: NavParams,
        public recipeData: RecipeDataProvider,
        public userData: UserDataProvider
    ) {}

    goToRecipe(recipeId: any){

    };

    printRecipeList(){
        console.log(this.recipeList);
    }


    ionViewDidLoad() {
        console.log('ionViewDidLoad RecipeListPage');
        this.recipeList = this.recipeData.recipeList;
    }

}

recipeList.html


    
        
        Recipe List
    




    

components.module.ts

import { NgModule } from '@angular/core';
import { RecipeCardComponent } from './recipe-card/recipe-card';
import { TimelineComponent } from './timeline/timeline';
import { TimerComponent } from './timer/timer';
@NgModule({
    declarations: [RecipeCardComponent,
    TimelineComponent,
    TimerComponent],
    imports: [],
    exports: [RecipeCardComponent,
    TimelineComponent,
    TimerComponent]
})
export class ComponentsModule {}

recipe-card.ts

import { Component, Input } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
// Providers
import { UserDataProvider } from "../../providers/user-data/user-data";
import { RecipeDataProvider } from "../../providers/recipe-data/recipe-data";
// Model
import { Recipe } from "../../models/recipe-model";
// Pages
import { RecipeDetailPage } from "../../pages/recipe-detail/recipe-detail";


@Component({
    selector: 'recipe-card',
    templateUrl: 'recipe-card.html'
})
export class RecipeCardComponent {

    @Input() recipe: Recipe;

    constructor(
        public navCtrl: NavController,
        public navParams: NavParams,
        private userData: UserDataProvider,
        private recipeData: RecipeDataProvider
    ) {}

    delete(){
        console.log('dalete recipe');
        // this.recipeData.delete(this.recipe.recipeId);
    }

    goToRecipeDetailPage() {
        console.log('goToRecipe() recipe');
        this.navCtrl.push('RecipeDetailPage', this.recipe);
    }

}

recipe-card.html



    
        

{{ recipe.title }}

{{ recipe.description }}

для полноты вот моя информация о ionic sys:

cli packages: (...)

    @ionic/cli-utils  : 1.12.0
    ionic (Ionic CLI) : 3.12.0

global packages:

    cordova (Cordova CLI) : 7.0.1

local packages:

    @ionic/app-scripts : 3.0.0
    Cordova Platforms  : none
    Ionic Framework    : ionic-angular 3.7.1

System:

    Node : v6.10.2
    npm  : 3.10.7
    OS   : Windows 10

Misc:

    backend : pro

Если я использую следующий код для recipe-card.html , он работает нормально . [+1123]

{{ recipe.title }}

{{ recipe.description }}

Но если я включу следующий код, значок иона вызывает ошибку разбора шаблона.

{{ recipe.title }}

{{ recipe.description }}

Таким образом, может показаться, что доступ к вложенным ионным встроенным компонентам в вашем собственном пользовательском компоненте идет не так. Это может быть что-то явно очевидное, что связано с отложенной загрузкой или общими компонентами.модуля, но я не вижу этого. Любая помощь будет отличной :) Заранее спасибо.

8
задан aidansmyth 6 October 2017 в 18:57
поделиться