2017-09-09 1 views
4

Jusqu'à présent, je n'ai pas trouvé un exemple simple de la façon de pousser des données dans un tableau dans Angular 2. Dans AngularJs c'était facile (example), mais je Je me bats pour cela dans Angular 2, peut-être parce que j'utilise un routeur et je ne sais pas comment le configurer (je suivais le heroes example angulaire).Comment faire pour pousser des données dans le tableau dans Angular 2 en utilisant route similaire

Ce que je veux faire, la solution complète:

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> 

Alors, quel est le problème ici: si je vais à Products-1 je reçois 10 produits, est évident, mais si j'appuie sur Show more alors les 10 premiers produits sont supprimés et 10 autres sont affichés - ce qui est encore évident, donc pour éviter cela et de garder la première 10 et la charge 10 plus, je l'ai remplacé Product.ts -> this.products = products; à:

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

Un autre problème apparaît maintenant: quand je vais à Product-2, les produits de Products-1 sont présentés ainsi que les produits de Product-2, afin d'éviter ce , j'ai ajouté ces deux lignes dans le Product.ts constructor:

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

maintenant, tout fonctionne bien sauf: quand je vais Products-1-Products-2 et charger d'autres produits, et après que le retour à Products-1, je peux voir dans mon réseau onglet que plusieurs demandes de même type sont en cours d'envoi à mon serveur.

Mes questions sont les suivantes:

  1. Y at-il une meilleure façon de pousser des données lors de l'utilisation de routage, et éviter de réinitialiser les paramètres dans le constructeur?
  2. Si le push dans le tableau est correct, et s'il est correct de réinitialiser les paramètres dans le constructeur, alors, comment éviter plusieurs requêtes en allant d'une route à l'autre?
+0

inscrivez-vous à routeParams vous obtenez les données du tableau? – Aravind

+0

oui, c'est correct – ToTa

+0

Avez-vous une solution pour cela ou besoin de plus d'aide – Aravind

Répondre

5

Il y a plusieurs choses que j'ajouter/changement product.ts:

  1. Ajouter ces propriétés sous votre index: number = 0; propriété:

    class_id: string; 
    type_id: string; 
    
  2. Retirez route.paramMap.subscribe du constructor

  3. ngOnInit, devrait ressembler à ceci:

    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. Et enfin, loadProducts():

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

+1, mais la boucle 'for' pourrait être remplacé par 'this.products = this.products.concat (productArray);', ce qui garantit qu'une nouvelle référence est créée. – cyrix

+1

Oui, je suis d'accord, je suivais juste sa logique, mais je vais mettre à jour la réponse maintenant – Ricka

0

dans Produit.ts:

import 'rxjs/add/operator/switchMap'; 
    import { Component, OnInit, OnDestroy } 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, OnDestroy { 
     subscribe:any; 
     products: Array<Product> = []; 
     numberOfObjectsPerPage: number = 10; 
     index: number = 0; 
     constructor(
      private productsService: ProductsService, 
      private route: ActivatedRoute 
     ) {} 

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

     loadProducts():void{ 
      this.subscribe=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 = this.products.concat(products); 
      }); 
     } 

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

    } 

utiliser Fondamentalement désinscrire procédé;

+0

toujours rien, j'ai compris que cela arrive parce que j'utilise le même chemin juste avec des paramètres différents, et angulaire n'appelle pas le 'détruire 'parce qu'il pense qu'il est sur le même chemin tout le temps, juste le service est appelé:' getProducts (..) ', voir ceci: https://stackoverflow.com/questions/40678321/angular2-ngondestroy-not-called-on-similar-route mais ce n'est pas utile non plus, donc je suis toujours coincé sur ce .. – ToTa