2017-08-10 78 views
1

我有2个组件。 CategoryComponent和CategoryProductComponent。我还有CartegoryService服务。 CategoryComponent返回一个表,其中包含从我的CategoryService中获取的类别列表。在表格的每一行上都有一个按钮,当点击该按钮时,将您从CategoryComponent转到CategoryProductComponent,它将向您显示该类别中的产品列表。组件之间的角度沟通

从我的API时,我得到的JSON,我有联系阵列上的rel =类别的产品,并有完整的链接一个href来获取相关产品。

现在的问题是,当我在CategoryComponent中获取json,并且当用户单击链接查看产品列表时,我得到该链接,然后调用CategoryService中的方法,然后将其分配给一个变量我将route.navigate称为CategoryProductComponent,它现在会在链接被分配后提取产品列表。

这时候我把网址手动在浏览器不工作,然后COS链接不是从CategoryComponent fectched。我读过服务是单身人士,所以我想这个变量至少会在第一次分配后保持填充状态。 我可以在我的组件之间进行这种通信的最佳方式。

而且我可以通过链接作为router.navigate一个额外的对象,但我没有看到这是理想特别是当人们决定直接在浏览器中输入URL。

category.component.ts

import { Category, FinalCategoryResponse, CategoryResponse, Link } from './category'; 
import { CategoryService } from './category.service'; 
import { Component, OnInit, OnDestroy } from '@angular/core'; 
import { Router } from '@angular/router'; 
import {Observable} from 'rxjs/Rx'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 

@Component({ 
    selector: 'app-category', 
    templateUrl: './category.component.html', 
    styleUrls: ['./category.component.css'] 
}) 
export class CategoryComponent implements OnInit, OnDestroy { 

    categories: Category[]; 
    categoryResponses: CategoryResponse[]; 
    constructor(private categoryService: CategoryService, private router: Router) { } 

    ngOnInit() { 
    this.categoryService.getCategories() 
     .subscribe(responseCategories => this.categoryResponses = responseCategories 
     , (err) => { 
     if (err.error instanceof Error) { 
     // A client-side or network error occurred. Handle it accordingly. 
     console.log('An error occurred:', err.error.message); 
     } else { 
     // The backend returned an unsuccessful response code. 
     // The response body may contain clues as to what went wrong, 
     console.log(`Backend returned code ${err.status}, body was: ${err.error}`); 
     } 
    }); 
    } 

    showCategoryProducts(categoryResponse: CategoryResponse , relName: string) { 
    const links: Link[] = categoryResponse.links; 
     for (const link of links) { 
     if (link.rel === relName) { 
      this.categoryService.assignCategoryProductLink(link.href); 
      this.router.navigate(['/categories', categoryResponse.category.id, 'products']); 
     } 
     } 
    } 


    ngOnDestroy(): void { 
     // unsubscribe to all subscriptions here 
     } 
} 

类别-service.ts

 import { Product } from '../product/product'; 
import { Category, FinalCategoryResponse, CategoryResponse } from './category'; 
import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 

@Injectable() 
export class CategoryService { 

    private categoryProductLink: string; 
    constructor(private http: Http) { } 

    getCategories() { 
    return this.http.get('http://localhost:8080/api/categories') 
     .map(response => <CategoryResponse[]>response.json()); 
    } 

    assignCategoryProductLink(link: string) { 
    this.categoryProductLink = link; 
    } 

    getCategoryProducts() { 
    return this.http.get(this.categoryProductLink) 
     .map(response => <Product[]>response.json()); 
    } 
} 

类别-product.component.ts

import { Product } from '../../product/product'; 
import { CategoryService } from '../category.service'; 
import { Component, OnInit, OnDestroy } from '@angular/core'; 

@Component({ 
    selector: 'app-category-product', 
templateUrl: './category.product-component.html', 
    styles: [] 
}) 
export class CategoryProductComponent implements OnInit, OnDestroy { 

    products: Product[]; 
    constructor(private categoryService: CategoryService) { } 

    ngOnInit() { 
    this.categoryService.getCategoryProducts() 
    .subscribe(results => this.products = results); 
    } 


ngOnDestroy(): void { 

    } 
} 

category.module

import { CategoryComponent } from './category.component'; 
import { CategoryService } from './category.service'; 
import { NgModule } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 
import { CategoryProductComponent } from './category-product/category-product.component'; 
import { CategoryRoutingModule } from './category-routing.module'; 
import { AddCategoryComponent } from './add-category/add-category.component'; 
import { ReactiveFormsModule } from '@angular/forms'; 

@NgModule({ 
    imports: [ 
    CommonModule, 
    CategoryRoutingModule, 
    ReactiveFormsModule 
    ], 
    declarations: [ 
    CategoryComponent, 
    CategoryProductComponent, 
    AddCategoryComponent 
    ], 
    exports : [CategoryComponent, CategoryProductComponent, AddCategoryComponent], 

    providers : [CategoryService] 
}) 
export class CategoryModule { } 

谢谢

+0

您已经发布了两次类别组件,而不是您的类别服务 – Steveland83

+0

还请提供父模块 - 需要声明两个组件并提供服务以便在组件之间共享相同的服务实例。 – Steveland83

+0

@ Steveland83我已经纠正了它 – user3701188

回答

2

我没有发现这一点,当我第一次看到你的问题。

这时候我把网址手动在浏览器中

使用角路由器不工作维护您的应用程序的状态,因为你没有实际航行的任何地方,当你使用它,但手动输入链接到您的浏览器意味着您深入链接到您的应用程序 - 我相当确定它失去了以前的任何状态,因为您正在有效地重新启动应用程序。

附注 - 我很惊讶,这是一个问题给你,当然这是预期的行为?

如果你真的想为这个要求,那么在CategoryService你可以localstorage存储数据如下:

setCategoryProductLink(link: string) { 
    localStorage.setItem('categoryProductLink', link); 
    } 

    getCategoryProductLink(): string { 
    return localStorage.getItem('categoryProductLink'); 
    } 

这将持续它的会话之间。

+0

我明白这是预期的行为,因为它并没有首先进入CategoryComponent,它没有链接从服务中获取产品。 使用本地存储意味着我将不得不至少一次。我无法直接进入categoryproductLink页面,而无需进入分类页面。 还有一个产品列表,每一次点击都会给出一个新的链接。 我可以做到这一点的另一种方式是不使用相关的链接,而只是从url浏览器获取id并相应地进行提取。但后来我没有机会使用我的rel链接。 – user3701188

+0

我所要求的是一种使用我的组件之间的rel链接的方式 – user3701188

+0

为什么不把url + localstorage方法结合起来。因此,在您的服务中,首先检查是否存在匹配的路由参数,如果没有,则查看localstorage。如果我理解正确,我认为这将处理您的两项要求。 – Steveland83