组件之间的角度通信

时间:2017-08-10 22:05:11

标签: angular typescript rxjs

我有2个组件。 CategoryComponent和CategoryProductComponent。我也有Cartegory服务。 CategoryComponent返回一个表,其中包含我从CategoryService中获取的类别列表。在表的每一行都有一个按钮,单击该按钮会将您从CategoryComponent带到CategoryProductComponent,它会显示该类别中的产品列表。

当我获得json时,从我的Api开始,我的链接数组有rel = category-product,并且有一个带有完整链接的href来获取相关产品。

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

当我在浏览器中手动输入url时,这不起作用,因为链接不会从CategoryComponent中导出。我读到服务是单例,所以我认为变量将至少在第一次分配后保持填充。 我可以用什么最好的方式在我的组件之间进行这种通信。

此外,我可以将链接作为额外对象传递给router.navigate,但我不认为这是理想的,特别是当一个人决定直接在浏览器中输入网址时。

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 { }

由于

1 个答案:

答案 0 :(得分:2)

当我第一次阅读你的问题时,我没有发现这一点。

  

当我在浏览器中手动输入网址时,这不起作用

使用Angular路由器可以维护您的应用程序状态,因为您在使用它时实际上并未在任何地方导航,但手动将链接输入浏览器意味着您已深入链接到您的应用程序 - 我我相当肯定它会失去之前的任何状态,因为你正在有效地重新启动应用程序。

旁注 - 我很惊讶这对你来说是一个问题,这肯定是预期的行为吗?

如果您确实要提供该要求,那么在CategoryService中您可以使用localstorage存储数据,如下所示:

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

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

这会在会话之间持续存在。