2017-11-22 18 views
1

私はionic 3アプリケーションで作業していますが、ヘッダー内の要素のわずかな違いだけで共通のヘッダーを持つページがいくつかあります。コードの重複を避け、DRYを維持するために、私はこのヘッダーの再利用可能なコンポーネントを作成し、必要なすべてのページにそれを含めようとしました。イオンアプリの一般的なヘッダー要素を作成する--prodビルド

このコンポーネントでは、プロパティバインディングを使用して要素の違いを制御するために使用するプロパティはほとんどありません。開発はすべてうまくいきます。しかし、今日--prodビルドを作成しようとすると、次のエラーが表示されます。

Error: Template parse errors: 
Can't bind to 'isHome' since it isn't a known property of 'ion-header'. 
1. If 'ion-header' is an Angular component and it has 'isHome' input, then verify that it is part of this module. 
2. If 'ion-header' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. 
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. (" 
    Ionic pages and navigation. 
--> 
<ion-header clean-header [ERROR ->][isHome]="true" (refresh)="refresh($event);"></ion-header> 

私は以下のコード、個々のファイルを添付します、私はこれが原因angular4/ionic3の依存性注入とテンプレート結合構造の私の誤解の問題であることを理解。しかし、私は与えられたエラーを理解することはできません、私は3つのソリューションをエラー自体に記載しようとしましたが、私はまだ何かが不足していると同じエラーのままです。

app.module.ts

import { BrowserModule } from '@angular/platform-browser'; 
import { ErrorHandler, NgModule } from '@angular/core'; 
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; 
import { SplashScreen } from '@ionic-native/splash-screen'; 
import { HTTP_INTERCEPTORS } from '@angular/common/http'; 
import { HttpClientModule } from '@angular/common/http'; 
import { StatusBar } from '@ionic-native/status-bar'; 
import { LaunchNavigator} from '@ionic-native/launch-navigator'; 

import { MyApp } from './app.component'; 
import { Header } from '../pages/header/header'; 
import { HomePage } from '../pages/home/home'; 
import {AssignmentDetailPage} from '../pages/assignment-detail/assignment-detail'; 
import { LoginPage } from '../pages/login/login'; 
import {ReportIssuePage} from '../pages/report-issue/report-issue'; 
import { AuthServiceProvider } from '../providers/auth-service/auth-service'; 
import { BaseUrl, Base } from './config/config.constants'; 
import { LoadingInterceptor } from '../interceptors/loading.interceptor'; 
import { DataStoreProvider } from '../providers/data-store/data-store'; 
import { HomeServiceProvider } from '../providers/home-service/home-service'; 
import { SessionInterceptor } from '../interceptors/session.interceptor'; 
import { AssignmentStatusProvider } from '../providers/assignment-status/assignment-status'; 
import { Camera } from '@ionic-native/camera'; 
import { File} from '@ionic-native/file'; 


@NgModule({ 
    declarations: [ 
    MyApp, 
    HomePage, 
    LoginPage, 
    Header, 
    AssignmentDetailPage, 
    ReportIssuePage 
    ], 
    imports: [ 
    BrowserModule, 
    HttpClientModule, 
    IonicModule.forRoot(MyApp, { 
     mode : 'md', 
    }) 
    ], 
    bootstrap: [IonicApp], 
    entryComponents: [ 
    MyApp, 
    HomePage, 
    LoginPage, 
    AssignmentDetailPage, 
    ReportIssuePage 
    ], 
    providers: [ 
    StatusBar, 
    SplashScreen, 
    {provide: ErrorHandler, useClass: IonicErrorHandler}, 
    {provide:Base, useValue:BaseUrl}, 
    {provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi:true}, 
    {provide: HTTP_INTERCEPTORS, useClass: SessionInterceptor, multi:true}, 
    AuthServiceProvider, 
    DataStoreProvider, 
    Camera, 
    File, 
    HomeServiceProvider, 
    AssignmentStatusProvider, 
    LaunchNavigator, 
    ] 
}) 
export class AppModule {} 

header.module.ts

import { NgModule } from '@angular/core'; 
import { Header } from './header'; 

@NgModule({ 
    declarations: [ 
    Header, 
    ], 
    imports: [ 
    ], 
    exports: [ 
    Header 
    ] 
}) 
export class HeaderModule {} 

header.ts

import { Component, EventEmitter, Input, Output } from '@angular/core'; 
import { AuthServiceProvider } from '../../providers/auth-service/auth-service'; 
import { AlertController, NavController } from 'ionic-angular'; 
import { HomePage } from '../home/home'; 
import { LoginPage } from '../login/login'; 
import { HomeServiceProvider } from '../../providers/home-service/home-service'; 

@Component({ 
    selector: '[clean-header]', 
    templateUrl: 'header.html', 
}) 
export class Header { 
    @Input() isHome: boolean = false; 
    @Output() refresh: EventEmitter<any> = new EventEmitter(); 
    public user: any; 
    constructor(public Auth: AuthServiceProvider, public nav: NavController, 
    public alertCtrl: AlertController, public HomeService: HomeServiceProvider) { 

    this.user = Auth.getUserData(); 
    } 

header.html

<ion-navbar hideBackButton> 
    <div text-center> 
    <img class="header-logo" src="./assets/imgs/clean_connect.png" alt="Logo of clean connect"> 
    </div> 
    <ion-grid> 
     <ion-row> 
     <ion-col col-8> 
      <div class="name-section"> 
      <h4 class="header-username">{{user.userName | uppercase}}</h4> 
      <p>{{user.firstName +', '+ user.lastName}}</p> 
      </div> 
     </ion-col> 
     <ion-col col-4 class="nav-controls"> 
      <a (click)="refreshData()" *ngIf="isHome"><img src="./assets/imgs/ic_refresh.png" alt="Logo of Refresh"></a> 
      <a (click)="goHome();" *ngIf="!isHome"><img src="./assets/imgs/home.png" alt="Logo of Home"></a> 
      <a (click)="logout()"><img src="./assets/imgs/logout.png" alt="Logo of Logout"></a> 
     </ion-col> 
     <ion-col col-2 class="nav-controls"> 

     </ion-col> 
     </ion-row> 
    </ion-grid> 
    </ion-navbar> 

<ion-header clean-header [isHome]="true" (refresh)="refresh($event);"></ion-header> 
<ion-content> 

最終的に私はこのような他の場所で、このコンポーネントを使用しています

home.htmlは、私は、カスタム要素ではなく属性としてそれを使用しようとした、しかし、それは目的のレイアウトを生成しません。 ion-headerとion-contentの間にカスタム要素があるので、angular1のようにtransclusionを使用する方法を見つけることができません。

私はこの質問がかなり長いことを知っていますが、私は実際のフィドルを作ることはできません。誰でも助けてくれますか?

+1

これは、Ionicチームによって推奨されていません。 ** [このSOの投稿](https://stackoverflow.com/questions/35936198/ionic-2-global-navbar-for-the-app/37808988#37808988)をご覧ください** – sebaferreras

+0

@sebaferrerasだから私は重複したコードをどこにでも保存しなければなりませんか?私はDRYの概念を奨励していないイオンフレームワークを選んだのは残念です。私は上記の行動を受け入れないための有効なポイントは見当たりません。 – Vignesh

+1

間違った考えをしないでください。 ** DRYのコンセプト**を奨励していますが、バックグラウンドでアプリの動作をアニメーション化し、UI/UXの観点からネイティブアプリに見えるようにすることがたくさんあります。コードの他の部分(ページ遷移など)を変更してヘッダコンポーネントですべてが正しく機能するようにするには、Ionicの内部的な詳細について深く知っておく必要があります。そのため、カスタムコンポーネントを使用しないことをおすすめします。 .. – sebaferreras

答えて

1

注:ベストプラクティスについての上記のアドバイスにもかかわらず、コンポーネントを作成する際に同様のエラーが発生したため、エラーを検索する他のユーザーに回答を提供しました。 私の場合、私はちょうど古いコンポーネントを持っていましたが、イオン・ラベルについて不平を言う以外は同じエラーがありました。初めてこれは私に掘削と試行錯誤のかなりのビットを取りに行くようになりました。私はトピックに関する明確でないドキュメンテーションを見つけました、または多分私はちょうどGoogleに正しいことを管理しませんでした。

あなたの header.module.tsなど app.module.tsIonicModuleをインポートする必要が

、すなわち

import { NgModule } from '@angular/core'; 
import { IonicModule } from 'ionic-angular'; 
import { Header } from './header'; 

@NgModule({ 
    declarations: [ 
    Header, 
    ], 
    imports: [ 
    IonicModule  // <-- add here 
    ], 
    exports: [ 
    Header 
    ] 
}) 
export class HeaderModule {} 

ライブリロードがこの変更を最初に逃すので、殺すために、イオン性再起動可能性があり注意してくださいするのに役立ちます。

次のバグレポートのコメントは、私はそれをうまく助け: https://github.com/angular/angular/issues/14288#issuecomment-282531453 https://forum.ionicframework.com/t/ionic-3-0-shared-component/91727/2

+0

はまだ同じエラーです。 – Vignesh

1

私は答えを見つけました。

しかし、イオンチームの勧告に基づいて、それがない に賢明である代わりに 内部の設計上の決定をイオン性に起因するすべてのページにヘッダを置く共通ヘッダを置きます。 sebaferrerasさんのアドバイスありがとうございます。私はコストを考慮せずに以下を行う人はお勧めしません。しかし、私はそれが可能であることを実証したかったのです。

しかし、私のイオン性ヘッダーにはいくつかの中間レベルの複雑な機能があり、私が使用するすべてのページでそれらをコピーする余裕がないので、まだ実装したいと思います。私は

1)/ app.module.tsからcomponent.tsは、app.module.tsからの成分の任意の輸入を除去

2)インポートIonicModuleをモジュールへの参照を削除し、以下のように実施しましたあなたのヘッダーのインポートセクション(再利用可能)モジュール(ヘッダ、module.ts)に

import { NgModule } from '@angular/core'; 
import { Header } from './header'; 
import {IonicModule} from "ionic-angular"; 

@NgModule({ 
    declarations: [ 
    Header, 
    ], 
    imports: [ 
    IonicModule 
    ], 
    exports: [ 
    Header 
    ] 
}) 
export class HeaderModule {} 

はその後、他のすべてのページのモジュールでHeaderModuleをインポート覚えていないcomponent.tsファイルではなく、そのファイルのモジュールで。

home.module.ts

import { NgModule } from '@angular/core'; 
import { IonicPageModule } from 'ionic-angular'; 
import { HomePage } from './home'; 
import {HeaderModule} from "../header/header.module"; 

@NgModule({ 
    declarations: [ 
    HomePage, 
    ], 
    imports: [ 
    IonicPageModule.forChild(HomePage), 
    HeaderModule, 
    ], 
    exports: [ 
    HomePage 
    ] 
}) 
export class HomePageModule {} 

この予想通り、私は任意の副作用に気づくことはありませんし、そのアニメーションの一部のために、私たちの現在のプロジェクトは、タイトルのアニメーションについてはあまり気にしない、そうであれば動作しますそれは私のユースケースでは問題ではありません。それに応じてユースケースを確認してください。

+1

あなたの答えにコメントを追加していただきありがとうございます:)また、見てください** [このSOの投稿](https://stackoverflow.com/questions/43164262/global-function-inionic 2-angular-2 )**を使用して、HTML属性を追加するだけでアプリ内のどこでも使用されるグローバル関数を作成する方法を確認できます。 – sebaferreras

関連する問題