Обмен данными между двумя несвязанными компонентами с использованием службы в angular 5 - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть два несвязанных компонента 'chatter-page' и 'header'.Мне нужно, чтобы некоторые данные были разделены и синхронизированы между этими двумя компонентамиЯ создал сервис, чтобы сделать то же самое.Это не работает.Справка

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

}

header.component ts file

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

Переменные fromDatePicker и toDatePicker, которые должны хранить значения из двух полей ввода даты (от даты до даты), которые присутствуют в обоих компонентах.sourceFilters, sentimentFilters, organizationFilters & categoryFilters - это наборы строк.

Мне нужно всегда синхронизировать значения fromDatePicker, toDatePicker, sourceFilters, sentimentFilters, organizationFilters & categoryFilters между обоими компонентами.Это мой фильтр общего ресурса

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

}

Что я делаю не так?Любая помощь приветствуется.TIA

1 Ответ

0 голосов
/ 26 апреля 2018

Удалите [provider] из компонента chatter-page и заголовка.

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 {


}

и

header-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.

...