2017-12-27 220 views
0

我是Angular的初学者,我开发了一个由5个组件组成的角4/5应用程序:A,B,C,D和E.所有这些组件都显示在单个(相同)页面上。组件A由导航栏中的下拉列表组成。现在,我要做的是,在组件A的下拉列表中选择任何特定选项后,我必须同时更改其他组件B,C,D和E的数据。如何根据Angular中的一个组件中的点击事件更改其他组件中的数据?

我非常困惑如何实现这种数据绑定。任何人都可以帮助如何实现这一目标?

由于发布整个代码将是一个非常困难的任务,因为我有大约二十个文件,所以我发布了组件A,组件B和根组件的代码。

组分A码,其中组分A是导航栏

导航bar.component.html:

<div class="container model-family-navigation-bar"> 
    <nav class="navbar navbar-expand-sm navbar-dark model-family-navigation-bar"> 
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" 
     aria-expanded="false" aria-label="Toggle navigation"> 
     <span class="navbar-toggler-icon"></span> 
    </button> 
    <div class="collapse navbar-collapse" id="navbarSupportedContent"> 
     <ul class="navbar-nav"> 
     <!-- <div class="col-sm-auto"> --> 
     <li class="nav-item dropdown"> 
      <a class="nav-link dropdown-toggle navigation-bar-content text-white" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" 
      aria-haspopup="true" aria-expanded="false"> 
      <span id="selected">Model Family</span> 
      </a> 
      <div class="dropdown-menu bg-success table-striped" aria-labelledby="navbarDropdown"> 
      <h1 class="dropdown-header text-white">Select Model Family</h1> 
      <div *ngFor="let item of dropdownElements"> 
       <div class="dropdown-divider"></div> 
       <a class="dropdown-item" (click)="showList()">{{item.model_family}}</a> 
      </div> 
      </div> 
     </li> 
     <!-- </div> --> 
     <!-- <div class="col-sm-auto"> --> 
     <li class="nav-item"> 
      <span class="navigation-bar-content navbar-text text-white ml-4">Proportional Directional Valve</span> 
     </li> 
     <!-- </div> --> 
     </ul> 

     <ul class="navbar-nav ml-auto"> 
     <li class="nav-item navbar-right"> 
      <a class="nav-link text-white" href="https://www.google.com/">Data Sheet</a> 
     </li> 
     </ul> 

    </div> 
    </nav> 
</div> 

导航bar.component.ts:

import { Component, OnInit } from '@angular/core'; 
import {NavigationDropdownElements} from './navigation-bar-dropdownElements' 

@Component({ 
    selector: 'navigation-bar', 
    templateUrl: './navigation-bar.component.html', 
    styleUrls: ['./navigation-bar.component.css'] 
}) 
export class NavigationBarComponent implements OnInit { 
    dropdownElements = NavigationDropdownElements; 

    ngOnInit() {} 

} 

导航-BAR-dropdownElements.ts

class NavigationDropdown{ 
    model_family: string; 
} 
export const NavigationDropdownElements: NavigationDropdown[] = [ 
    { model_family: 'CP210-1'}, 
    { model_family: 'CP211-2'}, 
    { model_family: 'CP212-3'} 
]; 

组分B的代码,其中组分B是模型家庭描述

模型家庭description.component.ts:

import { Component, OnInit } from '@angular/core'; 
import { descriptionElements1, descriptionElements2 } from './model-family-description-elements'; 
@Component({ 
    selector: 'model-family-description', 
    templateUrl: './model-family-description.component.html', 
    styleUrls: ['./model-family-description.component.css'] 
}) 
export class ModelFamilyDescriptionComponent implements OnInit { 
    desc1 = descriptionElements1; 
    desc2 = descriptionElements2; 
    constructor() { } 

    ngOnInit() { 
    } 

} 

model-family-description.component.html

<div class="container border-section"> 
    <div class="row"> 
    <p class="ml-2">{{desc2.description}}</p> 
    </div> 
</div> 

模型家庭描述-elements.ts

class ModelFamilyDescription { 
    description: string; 
} 

export const descriptionElements1: ModelFamilyDescription = 
    { description: 'This is a proportional, 3 position 4 way, directional control valve.' }; 

export const descriptionElements2: ModelFamilyDescription = 
    { description: 'This is a proportional, 4 position 5 way, non-directional control valve.' }; 

根组件:

app.component.html:

<navigation-bar></navigation-bar> 
<model-family-description></model-family-description> 

app.component.ts :

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

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 

} 

请帮忙。

+0

你必须使用输入参数和输出参数.. plz发布您的代码 –

+0

@federicoscamuzzi,我发布了我的代码。请帮忙。 – DG4

回答

0

应创建一个共同@InjectableSubject

实施例:

@Injectable() 
export class CommonService { 

    private dropdownValue: Subject<string> = new Subject(); 

    public getDropdownValue() : Observable { 
     return this.dropdownValue.asObservable(); 
    } 

    public setDropdownValue(value: string) : void { 
     this.dropdownValue.next(value); 
    } 

然后,在组分A:

constructor(
    private commonService: CommonService 
) { 
    ... 
} 

protected onDropdownChange(value: string) : void { 
    this.commonService.setDropdownValue(value); 
}   

而在其它组分:

constructor(
    private commonService: CommonService 
) { 
    this.commonService.getDropdownValue().subscribe((newValue) => { 
     // action on data change 
    }); 
} 
+0

我也发布了我的代码。你可以进一步编辑你的代码吗? – DG4

+0

如果你不能编辑你的代码,那么你能告诉我我需要为CommonService类创建一个单独的文件还是应该放入另一个我已经开发的类? – DG4

+0

一个文件=一个类:) – szmitas

0

首先创建一个服务是不是不像EventEmitter 的角度实施的功能了解更多关于主题从rxjs的文档:

message.service.ts

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs'; 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class MessageService { 
    private subject = new Subject<any>(); 

    sendMessage(message: string) { 
     this.subject.next({ text: message }); 
    } 

    clearMessage() { 
     this.subject.next(); 
    } 

    getMessage(): Observable<any> { 
     return this.subject.asObservable(); 
    } 
} 

然后该服务添加到app.module.ts

import { NgModule } from '@angular/core'; 
import { BrowserModule } from '@angular/platform-browser'; 
import { FormsModule } from '@angular/forms'; 

import { AppComponent } from './app.component'; 

import { MessageService } from './message.service'; 

@NgModule({ 
    imports:  [ 
    BrowserModule, 
    FormsModule, 
    ModalModule.forRoot() 
    ], 
    declarations: [ 
    AppComponent 
    ], 
    providers: [ 
    MessageService 
    ], 
    bootstrap: [ 
    AppComponent 
    ] 
}) 
export class AppModule { } 

现在你需要导入服务在您想从发送数据(A成分在你的情况下)的组件

类似:

import { Component, OnInit } from '@angular/core'; 
import {NavigationDropdownElements} from './navigation-bar-dropdownElements' 

import { MessageService } from './message.service'; 

@Component({ 
    selector: 'navigation-bar', 
    templateUrl: './navigation-bar.component.html', 
    styleUrls: ['./navigation-bar.component.css'] 
}) 
export class NavigationBarComponent implements OnInit { 
    dropdownElements = NavigationDropdownElements; 

    constructor(private messageService: MessageService) {} 

    sendMessage(data:string): void { 
    // send message to subscribers via observable subject 
    this.messageService.sendMessage(data); 
    } 

    showList() { 
    //on a click, you send the message here 
    let message:string="data example"; 
    this.sendMessage(message); 
    } 

    clearMessage(): void { 
    // clear message 
    this.messageService.clearMessage(); 
    } 

    ngOnInit() {} 

} 

而finaly你必须导入服务要阅读信息或数据的组件从第一组件(例如组分B)

像接受:

import { Component, OnInit, OnDestroy} from '@angular/core'; 
import { descriptionElements1, descriptionElements2 } from './model-family-description-elements'; 
import { Subscription } from 'rxjs/Subscription'; 

import { MessageService } from './message.service'; 
@Component({ 
    selector: 'model-family-description', 
    templateUrl: './model-family-description.component.html', 
    styleUrls: ['./model-family-description.component.css'] 
}) 
export class ModelFamilyDescriptionComponent implements OnInit { 
    //you receive the data in this variable --> message 
    message: any; 
    subscription: Subscription; 

    desc1 = descriptionElements1; 
    desc2 = descriptionElements2; 

    constructor(private messageService: MessageService) { 

    } 

    ngOnDestroy() { 
    // unsubscribe to ensure no memory leaks 
    this.subscription.unsubscribe(); 
    } 

    ngOnInit() { 
    // subscribe to component A messages 
    this.subscription = this.messageService.getMessage().subscribe(message => { this.message = message; }); 
    } 

} 
0

您需要发出下拉选项组件A的更改

然后使用设置器方法接收组件B和C的更改。 安装程序方法总是在期间被调用,更新值为

入住这里:https://stackblitz.com/edit/angular-dshm6g

您还可以使用可观察的模式从rxJs来解决这类问题。

相关问题