简体   繁体   English

在Angular 6的初始组件之间共享服务API数据

[英]Share service API data between initial components in Angular 6

I'm trying to have a navbar with categories and a home component that also uses those categories. 我正在尝试使用带有类别的导航栏和也使用这些类别的home组件。 I don't want to have to call my API twice and I will use that same categories variable in other places. 我不想调用我的API两次,我将在其他地方使用相同的category变量。 I tried doing the following: 我尝试执行以下操作:

Data Service 数据服务

This service gets the data from the api url and returns the subscribable object. 该服务从api网址获取数据并返回可订阅的对象。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  api_url: string = "https://apiurlhere";
  categories: Object;

  constructor(private http: HttpClient) { }

  getCategories(){
    return this.http.get(this.api_url+'/categorylisting/?z=1');
  }

  getZones(){
    return this.http.get(this.api_url+'/zones/');
  }

}

Navbar Component 导航栏组件

The Navbar component makes use of the categories variable to show the different options, this works fine since the subscribe is in this component. 导航栏组件利用category变量显示不同的选项,因为订阅位于该组件中,因此可以很好地工作。

import { Component, OnInit } from '@angular/core';
import { trigger, state, transition, animate, style } from '@angular/animations';
import { DataService } from '../data.service';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  animations: [
    trigger('slideInOut', [
      state('in', style({
        overflow: 'hidden',
        height: '*'
      })),
      state('out', style({
        overflow: 'hidden',
        height: '0px'
      })),
      transition('in => out', animate('400ms ease-in-out')),
      transition('out => in', animate('400ms ease-in-out'))
    ])
  ]
})
export class NavbarComponent implements OnInit {

  categories: Object;

  constructor(private data:DataService) { }

  ngOnInit() {
    this.data.getCategories().subscribe( data => {
      this.categories = data
      for(let category in this.categories){
        this.categories[category].productsOpen='out';
        for(let product in this.categories[category].product){
          this.categories[category].products[product].active = false;
        }
      }
      this.data.categories = this.categories;
    });
  }

  openProducts(index){
    this.categories[index].productsOpen = this.categories[index].productsOpen === 'out' ? 'in' : 'out';
  }

  setActiveProduct(index, productIndex){
    for(let category in this.categories){
      for(let product in this.categories[category].products){
        this.categories[category].products[product].active = false;
      }
    }
    this.categories[index].products[productIndex].active = true;
  }

}

Home Component 家庭组件

My Home component also makes use of the categories variable, so I want to know how I can get it here since it is always undefined even if it changes in the service. 我的Home组件还利用Categories变量,所以我想知道如何在这里获取它,因为即使在服务中发生更改,它也始终是未定义的。

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

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

  categories: Object;

  constructor(private data:DataService) { }

  ngOnInit() {
    this.categories = this.data.categories;
  }

}

Am I doing this right? 我这样做对吗? I'm used to react and redux and in there the render method would run every time a setState was called to change the state, when does angular know when the component's variables have changed? 我习惯于进行响应和还原,并且在那里,每次调用setState更改状态时,render方法都会运行,何时angular知道组件的变量何时更改? I just want to save a global variable with my data so I can reuse it without calling the API every time. 我只想用数据保存一个全局变量,这样我就可以重复使用它而无需每次都调用API。 Thank You. 谢谢。

You can cache the observable in your service like: 您可以在服务中缓存可观察对象,例如:

export class DataService {

someProperty;

  api_url: string = "https://apiurlhere";
  categories: Object;

  constructor(private http: HttpClient) { }

  getCategories(){
   if(!this.someProperty) {
     this.someProperty = this.http.get(this.api_url+'/categorylisting/?z=1');
   }
     return this.someProperty;
  }
}

You can also go for angular Http interceptors else you can also opt for rxjs operator shareReplay 您也可以使用有角度的Http拦截器,否则您也可以选择rxjs运算符shareReplay

You could try calling your API in the constructor of the DataService 您可以尝试在DataService的构造函数中调用API

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  api_url: string = "https://apiurlhere";
  categories: Object;

  constructor(private http: HttpClient) { 
    this.getCategories().subscribe(data => this.categories = data);
  }

  getCategories(){
    return this.http.get(this.api_url+'/categorylisting/?z=1');
  }

  getZones(){
    return this.http.get(this.api_url+'/zones/');
  }

}

and then just get the categories in the NavBar component just as you did in the Home component. 然后就像在Home组件中一样在NavBar组件中获取类别。

  ngOnInit() {
    this.categories = this.data.categories;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM