【问题标题】:How to make each angular component have a different array values如何使每个角度分量具有不同的数组值
【发布时间】:2019-03-31 23:20:40
【问题描述】:

我有一个角度组件,它显示来自 API 的加密货币价格。在同一个服务中,我为每个组件都有一组硬编码的星级值。当我遍历 API 中的每个值时,我还创建了一个内部 for 循环来遍历对象文字的硬编码数组,并附加唯一的数组值以对每个加密组件进行评级。旧版本(已注释掉)有效,但显示所有加密组件的相同评级信息。现在我将其注释掉并在数组中放入更多值以使其更简单。这是代码。我没有收到任何错误,只有控制台中未定义,并且评级组件停止显示在加密组件中。

getProducts() {
        return this.http.get('https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH,IOT,TRX&tsyms=USD')
  .map(result => {
    Object.keys(result).forEach(value => {

      // add logic to have each crypto a different rating
      var ratings = [{rating: 4, numOfReviews: 2}, {rating:5, numOfReviews: 3}, {rating:6, numOfReviews:1}];
      for(var i = 0; i < ratings.length; i++) {
        result[value]['ratingInfo'] = ratings[i].rating;
        result[value]['ratingInfo'] = ratings[i].numOfReviews;
      }

    /*  result[value]['ratingInfo'] = {
        imageUrl: "http://loremflickr.com/150/150?random=1",
        productName: "Product 1",
        releasedDate: "May 31, 2016",
        description: "Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.",
        rating: 4,
        numOfReviews: 2
      }*/
    });
    return result;
  });
}

Crypto.component.ts

import { Component } from '@angular/core';
import { ProductService } from './product.service';
import { RatingComponent } from './rating.component';
@Component({
  selector: 'crypto',
  styleUrls: ['./app.component.css'],
  template: `<h2 class="header">Crypto Price Compare</h2>
    <div *ngIf="cryptos">
    <div id="crypto-container" *ngFor="let crypto of objectKeys(cryptos)">
      <span class="left">{{ crypto }}</span>
      <span class="right">{{ cryptos[crypto].USD | currency:'USD':true }}</span>
      <br />
      <rating
      [rating-value]="cryptos[crypto].ratingInfo.rating"
      [numOfReviews]="cryptos[crypto].ratingInfo.numOfReviews">
  </rating>
    </div>
  </div>`
})
export class CryptoComponent {
  objectKeys = Object.keys;
cryptos: any;
ratings: any;

constructor(private _data: ProductService) {

}

ngOnInit() {
  this._data.getProducts()
    .subscribe(res => {
      this.cryptos = res;
      console.log(res);
    });

  //this.ratings = this._data.getRatings();
    console.log(this.ratings);


}

    onClick($event){
      console.log("Clicked",$event)
    }
}

【问题讨论】:

    标签: javascript arrays angular for-loop


    【解决方案1】:

    您可能希望像这样更改 ProductService 的实现:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { map } from 'rxjs/operators';
    
    @Injectable()
    export class ProductService {
    
      constructor(private http: HttpClient) { }
      ...
      getProducts() {
    
        const ratings = [
          { rating: 4, numOfReviews: 2 }, 
          { rating: 5, numOfReviews: 3 }, 
          { rating: 6, numOfReviews: 1 },
          { rating: 7, numOfReviews: 4 }
        ];
    
        return this.http.get('https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH,IOT,TRX&tsyms=USD')
          .pipe(
            map(
              cryptos => {
                const currencies = [];
                let index = 0;
                return Object.keys(cryptos).map((cryptoName, index) => {
                  return {
                    name: cryptoName,
                    price: cryptos[cryptoName].USD,
                    ratingInfo: { ...ratings[index] }
                  }
                });
              }
            )
          )
      }
      ...
    }
    

    这样做将导致getProducts() 方法返回一个Array 对象,您可以在视图中简单地循环。

    在您的 CryptosComponent 模板中,您可以执行以下操作:

    <h2 class="header">Crypto Price Compare</h2>
      <div *ngIf="cryptos">
      <div id="crypto-container" *ngFor="let crypto of cryptos">
        <span class="left">{{ crypto.name }}</span> - 
        <span class="right">{{ crypto.price | currency:'USD' }}</span>
        <br />
        <rating
          [ratingValue]="crypto.ratingInfo.rating"
          [numOfReviews]="crypto.ratingInfo.numOfReviews">
        </rating>
      </div>
    </div>
    

    注意:

    1. 我已将rating-value 的名称更改为ratingValue
    2. 此示例使用 Angular 7,其中任何需要应用于 Observable 的运算符都需要通过 pipe 运算符为 piped。如果您使用的是 Angular 4 或 5,则需要以与现在相同的方式进行操作,将 .map 链接到 Observable 值。

    这里有一个Sample StackBlitz 供您参考。

    【讨论】:

    • 嘿,抱歉回复晚了。谢谢你这么详细的回答。不幸的是,我收到Can't bind to 'ratingValue' since it isn't a known property of 'rating'. 错误。我不明白你所说的ratingInfo: { ...ratings[index] } 是什么意思... 是什么?如果我删除它,我的 IDE 会显示语法错误
    • Ups,我的错,我的代码中有错字,从 ratingValue 更改为 rating-value。感谢您提供示例代码!
    【解决方案2】:

    不确定你到底想做什么,但这没有意义。

    result[value]['ratingInfo'] = ratings[i].rating;
    result[value]['ratingInfo'] = ratings[i].numOfReviews;
    

    您正在设置 ratingInfo 并立即用其他内容覆盖它。假设 ratingInfo 是一个对象,你可能想要这样的东西:

    result[value]['ratingInfo']['rating'] = ratings[i].rating;
    result[value]['ratingInfo']['numOfReviews'] = ratings[i].numOfReviews;
    

    或者更简单地说:

    result[value]['ratingInfo'] = ratings[i]
    

    【讨论】:

    • 您的选项都不起作用。如果,我正在覆盖它,那么注释掉的部分怎么会起作用而不是覆盖呢?我用加密组件代码更新了我的问题以使其更有意义
    • 一切正常。我只需要弄清楚如何遍历更多的评级选项,而不仅仅是为每个 API 调用值分配一个也是唯一的评级信息(注释掉的部分)
    • 现在我明白你的意思了。是的,我将其更改为不覆盖。我什至使用硬编码的数字来分配值,而不是遍历数组,但我仍然得到core.js:1673 ERROR TypeError: Cannot set property 'rating' of undefined
    • 这个错误正是它听起来的样子。看看 core.js 中的 1673。您需要弄清楚为什么要对未定义的事物调用 .rating。
    • 我不明白 ['ratingInfo'] 在分配对象字面量的一个硬编码值时未定义,但在迭代时从数组中分配 rating 值时未定义。
    猜你喜欢
    • 2019-06-09
    • 2021-01-18
    • 2020-08-03
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    相关资源
    最近更新 更多