使用角度为5的服务在两个不相关的组件之间共享数据

时间:2018-04-26 07:14:26

标签: javascript html angular typescript angular-services

我有两个不相关的组件' chatter-page'和'标题'。我需要在这两个组件之间共享和同步一些数据。我已经创建了一个服务来做同样的事情。它不起作用。帮助

chatter-page.component ts file



import { Component, OnInit } from '@angular/core';
import { HostListener } from '@angular/core';
import { DatePipe } from '@angular/common';
import { DropdownItem } from '../shared/dropdownItem';
import { ChatterCard } from '../shared/chattercard';
import { ChatterService } from '../services/chatter.service';
import { FilterShareService } from '../services/filter-share.service';

@Component({
  selector: 'app-chatter-page',
  templateUrl: './chatter-page.component.html',
  styleUrls: ['./chatter-page.component.scss'],
  providers : [FilterShareService]
})
export class ChatterPageComponent implements OnInit {

  batchSize : number = 50;  

  dateFilterDisplayFlag : boolean = false;

  filterFlag : boolean;
  
  loaderFlag : boolean;

  competitors : string[] = ['Company1','Company2'];

  categories : string[] = ['Category1','Category2','Category3'];

  chatterCards : ChatterCard[] = [];    

  fromDatePicker;toDatePicker;

  dateDisplayFilter : string;
  
  sourceFilters : Set<string>;

  sentimentFilters : Set<string>;

  organizationFilters : Set<string>;

  categoryFilters : Set<string>;

  serviceCallString : string = "";

  scrollId : string = "";

  sourceDropdown : DropdownItem[] = [
    { icon: "fab fa-facebook-f", name: "Facebook" },
    { icon: "fab fa-twitter", name: "Twitter"}
  ];
  
  sentimentDropdown : DropdownItem[] = [
    { icon: "far fa-smile", name: "Positive" },
    { icon: "far fa-frown", name: "Negative" },
    { icon: "far fa-meh", name: "Neutral"}
  ];

  competitorDropdown : DropdownItem[] = [];

  categoryDropdown : DropdownItem[] = [];
  
  constructor(private datePipe : DatePipe, private chatterService : ChatterService, private filterShareService : FilterShareService) { }

  @HostListener("window:scroll", [])
  onScroll(): void {
    let windowHeight = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
    let body = document.body, html = document.documentElement;
    let docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
    let windowBottom = windowHeight + window.pageYOffset;
    if (windowBottom >= docHeight) {
      console.log("Bottom reached");
      this.addDisplayCards();
    }
  }

  receiveFilterFlag(){
    this.filterFlag = !this.filterFlag;    
  }

  sourceFilterEvent(filter){    
    let filters = this.sourceFilters;
    this.sourceFilters.has(filter.toUpperCase())? filters.delete(filter.toUpperCase()) : filters.add(filter.toUpperCase());
    this.filterShareService.changeSourceFilters(filters);
  }

  sentimentFilterEvent(filter){
    let filters = this.sentimentFilters;    
    this.sentimentFilters.has(filter.toUpperCase())? filters.delete(filter.toUpperCase()) : filters.add(filter.toUpperCase());
    this.filterShareService.changeSentimentFilters(filters);    
  }

  orgFilterEvent(filter){    
    if(!this.organizationFilters.has(filter.toLowerCase())){
      let filters = this.organizationFilters;
      filters.clear();
      filters.add(filter.toLowerCase());
      this.filterShareService.changeOrganizationFilters(filters);
    }    
  }

  categoryFilterEvent(filter){
    let filters = this.categoryFilters;
    this.categoryFilters.has(filter.toUpperCase())? filters.delete(filter.toUpperCase()) : filters.add(filter.toUpperCase());
    this.filterShareService.changeCategoryFilters(filters);    
  }

  fromDateEvent(){    
    let from = new Date(this.fromDatePicker);
    let fromDate = this.datePipe.transform(from, 'yyyy-MM-dd');
    this.filterShareService.changeFromDate(fromDate);    
    this.calculateDateDisplayFilter();
    this.dateFilterDisplayFlag = true;
  }

  toDateEvent(){
    let to = new Date(this.toDatePicker);
    let toDate = this.datePipe.transform(to, 'yyyy-MM-dd');
    this.filterShareService.changetoDate(toDate);
    this.calculateDateDisplayFilter();
    this.dateFilterDisplayFlag = true;
  }  

  calculateDateDisplayFilter(){
    this.dateDisplayFilter = this.fromDatePicker + " to " + this.toDatePicker;    
  }

  defaultDateFilter(){
    this.dateSetter(180);
  }  

  yesterdayDateFilter(){        
    this.dateSetter(1);
    this.dateFilterDisplayFlag = true;            
  }

  weekDateFilter(){
    this.dateSetter(7);
    this.dateFilterDisplayFlag = true;
  }

  monthDateFilter(){
    this.dateSetter(30);
    this.dateFilterDisplayFlag = true;
  }

  dateSetter(num){
    let from = new Date();
    from.setDate(from.getDate()-num);
    let fromDate =  this.datePipe.transform(from, 'yyyy-MM-dd');
    let toDate =  this.datePipe.transform(new Date(), 'yyyy-MM-dd');
    this.filterShareService.changeFromDate(fromDate);
    this.filterShareService.changetoDate(toDate);
    this.calculateDateDisplayFilter();
  }

  populateDropDowns(){
    this.competitors.forEach((competitor) => {
      this.competitorDropdown.push({ icon: "", name: competitor});
    });
    this.categories.forEach((category) => {
      this.categoryDropdown.push({ icon: "", name: category});
    });
  } 

  ngOnInit() {
    this.populateDropDowns();
    this.filterShareService.currSourceFilters.subscribe((filters) => this.sourceFilters = filters);
    this.filterShareService.currSentimentFilters.subscribe((filters) => this.sentimentFilters = filters);
    this.filterShareService.currOrganizationFilters.subscribe((filters) => this.organizationFilters = filters);
    this.filterShareService.currCategoryFilters.subscribe((filters) => this.categoryFilters = filters);    
    if(!(this.fromDatePicker && this.toDatePicker)) this.defaultDateFilter();
    this.filterShareService.currFromDate.subscribe((date) => this.fromDatePicker = date);
    this.filterShareService.currtoDate.subscribe((date) => this.toDatePicker = date);    
    this.applyFilters();        
  }

}
&#13;
&#13;
&#13;

header.component ts file

&#13;
&#13;
import { Component, OnInit } from '@angular/core';
import { DatePipe } from '@angular/common';
import { DropdownItem } from '../shared/dropdownItem';
import { FilterShareService } from '../services/filter-share.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
  providers: [FilterShareService]
})
export class HeaderComponent implements OnInit {

  dateFilterDisplayFlag : boolean = false;

  filterFlag : boolean;    

  competitors : string[] = ['Company1','Company2'];

  categories : string[] = ['Category1','Category2','Category3'];

  fromDatePicker;toDatePicker;

  dateDisplayFilter : string;
  
  sourceFilters : Set<string>;

  sentimentFilters : Set<string>;

  organizationFilters : Set<string>;

  categoryFilters : Set<string>;

  sourceDropdown : DropdownItem[] = [
    { icon: "fab fa-facebook-f", name: "Facebook" },
    { icon: "fab fa-twitter", name: "Twitter"}
  ];
  
  sentimentDropdown : DropdownItem[] = [
    { icon: "far fa-smile", name: "Positive" },
    { icon: "far fa-frown", name: "Negative" },
    { icon: "far fa-meh", name: "Neutral"}
  ];

  competitorDropdown : DropdownItem[] = [];

  categoryDropdown : DropdownItem[] = [];
  
  constructor(private datePipe : DatePipe, private filterShareService : FilterShareService) { }

  receiveFilterFlag(){
    this.filterFlag = !this.filterFlag;    
  }

  sourceFilterEvent(filter){    
    let filters = this.sourceFilters;
    this.sourceFilters.has(filter.toUpperCase())? filters.delete(filter.toUpperCase()) : filters.add(filter.toUpperCase());
    this.filterShareService.changeSourceFilters(filters);
  }

  sentimentFilterEvent(filter){
    let filters = this.sentimentFilters;    
    this.sentimentFilters.has(filter.toUpperCase())? filters.delete(filter.toUpperCase()) : filters.add(filter.toUpperCase());
    this.filterShareService.changeSentimentFilters(filters);    
  }

  orgFilterEvent(filter){    
    if(!this.organizationFilters.has(filter.toLowerCase())){
      let filters = this.organizationFilters;
      filters.clear();
      filters.add(filter.toLowerCase());
      this.filterShareService.changeOrganizationFilters(filters);
    }    
  }

  categoryFilterEvent(filter){
    let filters = this.categoryFilters;
    this.categoryFilters.has(filter.toUpperCase())? filters.delete(filter.toUpperCase()) : filters.add(filter.toUpperCase());
    this.filterShareService.changeCategoryFilters(filters);    
  }

  fromDateEvent(){
    console.log("Inside dash header")    
    let from = new Date(this.fromDatePicker);
    let fromDate = this.datePipe.transform(from, 'yyyy-MM-dd');
    this.filterShareService.changeFromDate(fromDate);    
    this.calculateDateDisplayFilter();
    this.dateFilterDisplayFlag = true;
  }

  toDateEvent(){
    let to = new Date(this.toDatePicker);
    let toDate = this.datePipe.transform(to, 'yyyy-MM-dd');
    this.filterShareService.changetoDate(toDate);
    this.calculateDateDisplayFilter();
    this.dateFilterDisplayFlag = true;
  } 

  calculateDateDisplayFilter(){
    this.dateDisplayFilter = this.fromDatePicker + " to " + this.toDatePicker;
  }

  defaultDateFilter(){
    this.dateSetter(180);
  }  

  yesterdayDateFilter(){        
    this.dateSetter(1);
    this.dateFilterDisplayFlag = true;            
  }

  weekDateFilter(){
    this.dateSetter(7);
    this.dateFilterDisplayFlag = true;
  }

  monthDateFilter(){
    this.dateSetter(30);
    this.dateFilterDisplayFlag = true;
  }

  dateSetter(num){
    let from = new Date();
    from.setDate(from.getDate()-num);
    let fromDate =  this.datePipe.transform(from, 'yyyy-MM-dd');
    let toDate =  this.datePipe.transform(new Date(), 'yyyy-MM-dd');
    this.filterShareService.changeFromDate(fromDate);
    this.filterShareService.changetoDate(toDate);
    this.calculateDateDisplayFilter();
  }

  populateDropDowns(){
    this.competitors.forEach((competitor) => {
      this.competitorDropdown.push({ icon: "", name: competitor});
    });
    this.categories.forEach((category) => {
      this.categoryDropdown.push({ icon: "", name: category});
    });
  }

  ngOnInit() {
    this.populateDropDowns();
    this.filterShareService.currSourceFilters.subscribe((filters) => this.sourceFilters = filters);
    this.filterShareService.currSentimentFilters.subscribe((filters) => this.sentimentFilters = filters);
    this.filterShareService.currOrganizationFilters.subscribe((filters) => this.organizationFilters = filters);
    this.filterShareService.currCategoryFilters.subscribe((filters) => this.categoryFilters = filters);
    if(!(this.fromDatePicker && this.toDatePicker)) this.defaultDateFilter();
    this.filterShareService.currFromDate.subscribe((date) => this.fromDatePicker = date);
    this.filterShareService.currtoDate.subscribe((date) => this.toDatePicker = date);
       
  }
}
&#13;
&#13;
&#13;

fromDatePicker和toDatePicker变量,它们应该存储两个组件中存在的两个日期输入字段(从日期到日期)的校准。 sourceFilters,sentimentFilters,organizationFilters&amp; categoryFilters是字符串集。

我需要同步fromDatePicker,toDatePicker,sourceFilters,sentimentFilters,organizationFilters&amp; categoryFilters始终在两个组件之间的值。这是我的过滤器共享服务

&#13;
&#13;
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class FilterShareService {

  private sourceFilters = new BehaviorSubject<Set<string>>(new Set<string>());
  currSourceFilters = this.sourceFilters.asObservable();

  private sentimentFilters = new BehaviorSubject<Set<string>>(new Set<string>());
  currSentimentFilters = this.sentimentFilters.asObservable();

  private organizationFilters = new BehaviorSubject<Set<string>>(new Set<string>(["vanguard"]));
  currOrganizationFilters = this.organizationFilters.asObservable();

  private categoryFilters = new BehaviorSubject<Set<string>>(new Set<string>());
  currCategoryFilters = this.categoryFilters.asObservable();

  private fromDate = new BehaviorSubject<string>("");
  currFromDate = this.fromDate.asObservable();

  private toDate = new BehaviorSubject<string>("");
  currtoDate = this.toDate.asObservable();

  constructor() { }

  changeFromDate(date: string){
    this.fromDate.next(date);
    console.log("Inside service");
    console.log(this.fromDate);
  }

  changetoDate(date: string){
    this.toDate.next(date);
  }

  changeSourceFilters(sourceFilters: Set<string>){
    this.sourceFilters.next(sourceFilters);
  }

  changeSentimentFilters(sentimentFilters: Set<string>){
    this.sentimentFilters.next(sentimentFilters);
  }

  changeOrganizationFilters(organizationFilters: Set<string>){
    this.organizationFilters.next(organizationFilters);
  }

  changeCategoryFilters(categoryFilters: Set<string>){
    this.categoryFilters.next(categoryFilters);
  }

}
&#13;
&#13;
&#13;

我做错了什么?任何帮助表示赞赏。 TIA

1 个答案:

答案 0 :(得分:1)

从聊天页面和标题组件中删除[provider]

import { Component, OnInit } from '@angular/core';
import { HostListener } from '@angular/core';
import { DatePipe } from '@angular/common';
import { DropdownItem } from '../shared/dropdownItem';
import { ChatterCard } from '../shared/chattercard';

@Component({
  selector: 'app-chatter-page',
  templateUrl: './chatter-page.component.html',
  styleUrls: ['./chatter-page.component.scss']
})
export class ChatterPageComponent implements OnInit {


}

头-component.ts

import { Component, OnInit } from '@angular/core';
import { DatePipe } from '@angular/common';
import { DropdownItem } from '../shared/dropdownItem';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
})
export class HeaderComponent implements OnInit {

}

拥有providers: [FilterShareService]表示您始终在启动服务。因此HeaderComponent将有一个新的独立FilterShareService,ChatterPageComponent将有一个单独的。这样他们就可以分享。

将其移至app.module.ts,如下所示。

@NgModule({
    imports: [

        BrowserModule,

    ],
    declarations: [
        HeaderComponent ,
        ChatterPageComponent 

    ],
    providers: [
        FilterShareService,
        ChatterService 
    ],
    bootstrap: [
        AppComponent
    ]
})

export class AppModule { }

现在,该服务将在AppModule下的所有模块中共享。