2017-01-01 74 views
0

我的應用程序是這樣的:如何使用angular2共享組件?

  1. 一些基本的組件(家庭,登錄,大約...)在我的主 app.module
  2. 一些其他模塊的應用程序的每個部分

我有一個組件,ToastComponent,我可能需要到處使用。 我工作正常的基本組件,但不包括在模塊中包含的那些。

我讀到有關如何共享服務,但是,(我一直不明白我在angular2承認),我仍然無法弄清楚如何使它工作在我的情況下,許多網頁。 (我甚至嘗試過sharedmodule,但它更糟糕)

我遇到的問題是給setMessage(見代碼結尾)的消息顯示在控制檯,但不是在屏幕上!?!

希望有人可以點我在正確的方式來編寫的。 TIA

JP

這裏是代碼後,我恢復到一個已知的階段(許多嘗試後)...

的ToastComponent:

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

@Component({ 
    selector: 'app-toast', 
    templateUrl: './toast.component.html', 
    styleUrls: ['./toast.component.css'] 
}) 
export class ToastComponent { 
    @Input() message = { body: '', type: '' }; 

    setMessage(body, type, time = 5000) { 
    this.message.body = body; 
    this.message.type = type; 
    console.log('ToastComponent %o' , this.message); 
    setTimeout(() => { this.message.body = ''; }, time); 
    } 
} 

app.module

import { ToastComponent }   from './_shared/toast.component'; 
... 
import { LivresModule }    from './livres/livres.module'; // where toast will be used 
import { ExampleComponent }   from './example.component'; // where toast is working fine 
... 
@NgModule({ 
    imports: [ ... , LivresModule ], 
    providers: [ ToastComponent, ... ], 
    declarations: [ AppComponent, ToastComponent, ... ] 
    exports: [ ToastComponent ], 
    schemas: [ CUSTOM_ELEMENTS_SCHEMA ], 
    bootstrap: [ AppComponent ], 
}) 
... 

livres.module.ts

... 
import { ToastComponent }   from '../_shared/toast.component'; 
import { AuteursComponent }   from './auteurs.component'; // where to use toast effectively 
... 
@NgModule({ 
... 
    providers: [ ToastComponent, ... ] 
    declarations: [ 
//  ToastComponent, // error as declared twice with app.module : OK so commented 
... 

auteurs.component

... 
import { ToastComponent }  from '../_shared/toast.component'; 
... 
constructor(private http: Http, private authorService: AuthorService, 
       private toast: ToastComponent) { } 
... 
addAuthor() { 
... 
    this.toast.setMessage('Auteur ajouté', 'success'); 
} 

auteurs.component.html

...<app-toast [message]="toast.message"></app-toast>... 

auteurs.component。*是app.module的組成部分工作正常的副本。


最新資訊: 我再造一個光的應用程序,模仿一個我建設,我有一個模塊在此錯誤頁:

Unhandled Promise rejection: Template parse errors: 
    Can't bind to 'message' since it isn't a known property of 'app-toast'. 
    1. If 'app-toast' is an Angular component and it has 'message' input, then verify that it is part of this module. 
    2. If 'app-toast' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. 
    ("<app-toast [ERROR ->][message]="toast.message"></app-toast> 
<p> page2 works! </p> 
<button (click)="displayMsg()"> Click !"): [email protected]:11 

這就是爲什麼我說「模式:[CUSTOM_ELEMENTS_SCHEMA]「(我忘記了這一點),但實際上它在編譯時隱藏了我在運行時遇到的錯誤!

轉換爲服務不會帶來HTML代碼和CSS它。

+1

你談論你得到的錯誤,但沒有包含在你的問題。 Plesse添加確切的錯誤消息。 –

+1

完全沒有錯誤:只有在使用setMessage時屏幕上才顯示的消息。 – JPMous

+0

您需要將您的Toast代碼設置爲服務。在這裏看到更好的實現:https://github.com/johnpapa/event-view –

回答

0

正如評論上面提到的,共享的服務可能是你所需要的。下面是一個共享服務的簡單實現,我希望它能幫助你理解共享服務,因爲你提到你很難理解它:)

因此,對於你來說,如果你有setMessage方法,然後在您的auteurs.component,你會注入該服務在您的構造函數,然後當你要更改消息的價值,像這樣你會調用該方法在服務:

this.sharedService.sharedMessage = // your new message here 

而只是檢索消息在你需要的所有組件中,如:

this.message = this.sharedService.sharedMessage; 

這就是你將如何訪問它。但看看下面的例子!

在這裏我已經實現了一個父組件和子組件,只是爲了展示它們是如何影響兩個組件中所做的更改的。我已經採取了一些引用您的代碼,作爲您要在您的應用程序中操縱的「類型」和「身體」。你可以象我在這個例子中那樣實現它,它總是在服務中被操縱,因此使用這個服務的所有組件都將具有與服務中存在的相同的值!我會添加一些一步一步的圖片以及:)你可以使你的ToastComponent的服務,您的訪問,你想:)

所以第一關,接口:

export interface IShared { 
    body: string; 
    type: string; 
} 

在我們建立了兩個組件將共享的sharedMessage的服務。我們也有針對sharedMessage

@Injectable() 
export class SharedService { 

    sharedMessage; 

    sharedMessage: IShared = { 
     body: 'old body', 
     type: 'old type', 
    }; 

    setMessage(body, type) { 
     this.sharedMessage.body = body; 
     this.sharedMessage.type = type; 
    } 

    constructor() { } 
} 

你的父母和孩子組成部分是在這種情況下,我給出幾乎相同的設置新內容的方法。我們都在構造函數中(是的,而是在OnInit中做),以便我們從服務中獲得消息的當前值。在這裏我們也有方法來操縱這個值。將在調用該值的共享服務中調用該方法的方法。所以,一旦你瞭解它,這其實並不困難。下面是父母和孩子的組件和html視圖。

你父組件:

HTML:

<h2>Hey, let's play with shared service!</h2> 
<button (click)="setMessage('new Body', 'new Type')">Set new (parent)</button> 
<h4>This message is in parent component: <b>{{message.body}}, {{message.type}}</b></h4> 
<br> 
<child-component></child-component> 

組件:

message; 

setMessage(body, type) { 
    this.message.body = body; 
    this.message.type = type; 
    this.sharedService.sharedMessage = this.message; 
} 

constructor(private sharedService: SharedService) { 
     this.message = this.sharedService.sharedMessage; 
} 

你的孩子組成:

HTML:

<button (click)="setMessage('newest Body', 'newest Type')">Set newest (child)</button> 
<h4>This message is in child component: <b>{{message.body}}, {{message.type}></b></h4> 

組件:

message; 

setMessage(body, type) { 
    this.message.body = body; 
    this.message.type = type; 
    this.sharedService.sharedMessage = this.message; 
} 

constructor(private sharedService: SharedService) { 
    this.message = this.sharedService.sharedMessage; 
} 

最後,讓呈現這個視圖。首先,我們將顯示在導航到也顯示子組件的父級時從共享服務獲得的值。所以我們顯示當前值並有按鈕來操作這個值。

enter image description here

然後當我們點擊父組件的按鈕,我們得到了雙方家長和孩子設置新的值,因爲它們共享相同的服務。

enter image description here

而且最後我們點擊子組件的按鈕:)

enter image description here

希望這有助於! :) :)