angular - 使用类似路由时如何将数据推送到 Angular 2 中的数组

标签 angular angular2-routing angular2-services

到目前为止,我还没有找到一个简单的例子来说明如何在 Angular 2 中将数据推送到数组中。在 AngularJs 中这很容易 ( example ),但我在 Angular 2 中苦苦挣扎,也许是因为我正在使用路由器,但我不知道如何配置它(我遵循的是 Angular heroes example )。

我想做的,整个解决方案:

app.module.ts:

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { HttpModule } from '@angular/http';
import { ProductsService } from '../services/ProductsService';


import { AppComponent } from "./components/app";
import { Products } from "./components/products";

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot([
            {
                path: 'products/:class_id/:type_id',
                component: Products
            }
        ], { useHash: true })
    ],
    exports: [RouterModule],
    declarations: [
        AppComponent
        Products
    ],
    providers: [
        ProductsService
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

AppComponent.ts

import { Component} from "@angular/core";

@Component({
    selector: "my-app",
    template: `<div>
                <a [routerLink]="['/products', 1, 1]">Products-1</a>
                <a [routerLink]="['/products', 2, 2]">Products-2</a>
               </div>`
})
export class AppComponent{}

ProductsService.ts

import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class ProductsService {

    private headers = new Headers({ 'Content-Type': 'application/json' });

    constructor(private http: Http) { }

    getProducts(class_id: string, type_id: string, index: number, numberOfObjectsPerPage: number): Promise<any> {
        return this.http.get('Home/GetProducts?pageIndex=' + index +'&classId=' + class_id + '&typeId=' + type_id)
            .toPromise()
            .then(response => response.json() as any)
            .catch(this.handleError);
    }

    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
}

Product.ts

import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import * as $ from 'jquery';

import { ProductsService } from '../../services/ProductsService';
import { Product } from '../../common/models/Product';

@Component({
    selector: 'products',
    templateUrl: 'Products.html',
})
export class Products implements OnInit {
    products: Array<Product> = [];
    numberOfObjectsPerPage: number = 10;
    index: number = 0;
    constructor(
        private productsService: ProductsService,
        private route: ActivatedRoute
    ) {}

    ngOnInit(): void {
        this.loadProducts();
    }

    loadProducts():void{
        this.route.paramMap
            .switchMap((params: ParamMap) =>
                this.productsService.getProducts(params.get('class_id'), params.get('type_id'), this.index, this.numberOfObjectsPerPage))
            .subscribe(products => {
                this.products = products;
        });
    }

    showMore():void{
        this.index++;
        this.loadProducts();
    }
}

Products.html:

<div class="product" *ngFor="let product of products;">
  {{ product.name }}
</div>
<button (click)="showMore()">Show more</button>

那么,这里的问题是什么:如果我转到 Products-1,我会得到 10 个产品,这很明显,但是如果我按 Show more,那么第一个删除了 10 个产品并显示了另外 10 个 - 这同样很明显,因此为了避免这种情况并保留前 10 个并再加载 10 个,我将 Product.ts -> this.products = products; 替换为:

 for (let i = 0; i < products.length; i++) {
  this.products.push(products[i]);
 }

现在出现另一个问题:当我转到 Product-2 时,来自 Products-1 的产品与 Product-2< 的产品一起显示,为了避免这种情况,我将这两行添加到 Product.ts 构造函数中:

constructor(private productsService: ProductsService, private route: ActivatedRoute) {
        route.paramMap.subscribe(params => this.products = []);
        route.paramMap.subscribe(params => this.index = 0);
}

现在,一切正常,除了:当我从 Products-1 转到 Products-2 并加载更多产品,然后返回到 Products -1,我可以在我的网络选项卡中看到多个相同类型的请求正在发送到我的服务器。

所以我的问题是:

  1. 有没有更好的方法在使用路由时推送数据,避免在构造函数中重新设置参数?
  2. 如果压入数组是可以的,如果在构造函数中重新设置参数是可以的,那么,如何避免从一个路由到另一个路由时的多次请求?

最佳答案

我要在 product.ts 中添加/更改几项内容:

  1. 在您的 index: number = 0; 属性下添加这些属性:

    class_id: string;  
    type_id: string;
    
  2. 构造函数

    中移除route.paramMap.subscribe
  3. ngOnInit,应该是这样的:

    ngOnInit(): void {
      this.route.paramMap.subscribe(params => {
        this.products = [];
        this.index = 0;
        this.type_id = params.get('type_id');
        this.class_id = params.get('class_id');
        this.loadProducts();
      });   
    }
    
  4. 最后,loadProducts():

    loadProducts(): void {
      this.productsService.getProducts(this.class_id, this.type_id, this.index, this.numberOfObjectsPerPage).then(
        productArray => {
             this.products = this.products.concat(productArray);
        })
    }
    

关于angular - 使用类似路由时如何将数据推送到 Angular 2 中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46132499/

相关文章:

javascript - 计算/获取隐藏的 div 宽度(以 Angular 为单位)

Angular Mat-form-field 占位符颜色

Angular 2 路由子节点和路由器导出

http - Ionic2,Angular2 :How to avoid CORS issue while using http get for REST API service call?

angular2 - 在组件之间传递数据对象

python - Pyramid CORS 不提供 PUT 和 DELETE 服务

javascript - Ionic 2/Angular 2 中的 NPM 模块 "only refers to a type, but is being used as a value here."

Angular2 RC.1 - 将路由器注入(inject)单元测试

angular - 为 Angular 2 配置 history.pushState

angular - 遇到未定义的提供者!通常这意味着你有一个循环依赖(可能是由于使用 'barrel' index.ts 文件引起的