如何与angular2一起使用共享组件? [英] how to use a shared component with angular2?

查看:75
本文介绍了如何与angular2一起使用共享组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序是这样构建的:

My application is built this way :


  1. 主$中有一些基本组件(主页,登录名,关于...) b $ b app.module

  2. 应用程序各部分的其他模块

I有一个组件ToastComponent,可能需要在任何地方使用。
我的基本组件工作正常,但不适用于模块中包含的组件。

I have a component, ToastComponent, that I may need to use everywhere. I works fine for basic components, but not for those included in a module.

我阅读了很多有关如何共享服务的页面(不了解我在angular2中承认的全部内容),但仍然无法弄清楚如何使其适用于我的情况。
(我什至尝试了一个共享模块,但情况更糟)

I read many pages about how to share a service, however (I do not understand all I admit in angular2), I still can't figure out how to make it works in my case. (I even tried a sharedmodule but it was worse)

我遇到的问题是,显示给setMessage的消息(请参见代码结尾)控制台,但不在屏幕上!?!

The issue I have is that the message given to setMessage (see end of code) is displayed in the console, but not on the screen !?!

希望有人可以指出正确的编码方式。
TIA

Hope someone could point me on proper way to code it. TIA

JP

这里是我回到已知阶段(之后很多尝试)...

Here are the code after I revert back to a known stage (after many tries)...

ToastComponent:

The 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

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

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

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

auteurs.component.html

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

auteurs.component。*是app.module正常工作的组件的副本。

auteurs.component.* is a copy of a component part of app.module that works fine.

新信息:
我正在重新创建一个模仿我bui的轻型应用程序lding,我在模块中的页面上遇到此错误:

NEW INFO : I am recreating a light app that mimics the one I am building, and I had this error for the page in a 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 !"): Page2Component@0:11

这就是为什么我添加了方案:[CUSTOM_ELEMENTS_SCHEMA](我忘记了这一点)的原因,但实际上,它在编译时隐藏了我在运行时遇到的错误!

That is why I added "schemas: [ CUSTOM_ELEMENTS_SCHEMA ]" (I've forgotten this), but in fact it hides an error at compile time that I have at runtime !

转换为服务不会带来html代码和CSS。

Converting to a service does not bring html code and css with it.

推荐答案

如上所述,共享服务可能是您所需要的。这是共享服务的简单实现,希望您能理解共享服务,因为希望您能理解共享服务:)

As mentioned in comment above, shared Service might be what you need. Here is below a simple implementation of a shared service, which I hope will help you understand shared services, since you mentioned you had trouble understanding it :)

因此,您将实现此共享服务具有 setMessage 方法的服务,然后在您的 auteurs.component 中,将该服务注入构造函数中,然后,当您想更改消息的值时,将在服务中调用该方法,如下所示:

So for you you would implement this shared service where you have the setMessage method, then in your auteurs.component, you would inject that service in your constructor, and then you would call that method in the service when you want to change the value of the message, like so:

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

然后在您需要的所有组件中检索该消息,例如:

And just retrieve that message in all your components you need it, like:

this.message = this.sharedService.sharedMessage;

,这就是您访问它的方式。但是,请看下面的示例!

and that's how you would have access to it. But look at the example below!

在这里,我实现了一个父级和子级组件,目的只是为了展示它们在这两个组件中所做的更改对它们的影响。我已经参考了您的代码,因为类型和身体您想在应用程序中进行操作。您可以像在本示例中一样实现它,它总是在服务中被操纵,因此,使用该服务的所有组件将具有与该服务中相同的值!我还将逐步添加一些图片:)您可以将 ToastComponent 作为服务从所需位置访问:)

Here I have implemented a parent and child component, just to show how they both are affected of changes done in either component. I've taken some to reference to your code, as the "type" and "body" you want to manipulate in you app. You could implemented it like I have in this example, that it always gets manipulated in the service, and therefore all components that use this service will have the same value as is present in the service! I'll add some step by step pictures as well :) You could make your ToastComponent as a service where you access it from where you want :)

因此,首先是一个接口:

So first off, an interface:

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

在服务中,我们设置了 sharedMessage 这两个组件将共享。我们还具有为 sharedMessage

In the service we set up the sharedMessage that both components will share. We also have the method of setting new content for that 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 中进行),以便我们从服务中获取message的当前值。在这里,我们还有控制该值的方法。将在共享服务中调用该值的方法的方法。因此,一旦您理解了它,实际上并不是那么困难。以下是父级和子级的组件和html视图。

Your parent and child components are practically identical in this case I present. In both we have in the constructor (yes, rather do it in OnInit though) so that we get the current value of message from the service. Here we also have method to manipulate that value. Methods that will call the method in the shared service that does the manipulation of the value. So this is actually not that difficult, once you understand it. Here follows the components and html views of both parent and child.

您的父级组件:

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;
}

最后,让我们介绍一下这个观点。首先,我们显示了从共享服务获得的价值,该价值在导航到还显示子组件的父项时得到。因此,我们将显示当前值并具有用于操作值的按钮。

And lastly, let present the view of this. First off we show the value we get from the shared service upon navigating to the parent that also shows the childcomponent. So we display the current values and have buttons to manipulate the value.

然后当我们单击父组件的按钮时,我们将为父和子设置新值,因为它们共享相同的服务。

Then when we click the button of the parent component, we get the new values set for both parent and child, since they share the same service.

最后,我们单击了子组件的按钮:)

And lastly we have clicked the child component's button :)

希望这会有所帮助! :):)

Hope this helps! :) :)

这篇关于如何与angular2一起使用共享组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆