【问题标题】:Why am I getting a duplicate addition to a string when I override it?为什么我在覆盖字符串时会重复添加字符串?
【发布时间】:2020-02-26 17:38:41
【问题描述】:

我的目标:从组件调用服务中的函数,这将返回一个字符串数组。

我第一次得到一个数组没问题。如: http://localhost:4200/assets/images/hardwoods/american_white_oak.png

但是当我浏览到另一个页面并再次访问同一页面时,我会得到一个附加的数组: http://localhost:4200/assets/images/hardwoods/american_white_oak.png.png (重复的“.png”)。

我不明白为什么每次更改页面时组件中的数组图像都没有被覆盖,为什么如果它没有被覆盖 - 为什么只添加“.png”字符串?

关于这部分代码的简短说明: 我正在调用服务中的函数。这个功能是: 1.创建一个新的字符串数组,从模型中的一个对象中分配一个数组给它。该对象由服务内部的构造函数创建。 2. 在其上和内部运行 for 循环: 做一些分裂/加入。 小写 从左右向其添加一个字符串。 退出 for 循环。 3. 返回修改后的数组。

组件的html文件

<ngb-carousel #carousel interval="3000" [pauseOnHover]="pauseOnHover" (slide)="onSlide($event)">
<ng-template ngbSlide *ngFor="let img of images; index as i">
  <div class="carousel-caption">
    <h3>{{imageNames[i]}}</h3>
  </div>
  <div class="picsum-img-wrapper">
    <img [src]="img" alt="img">
  </div>
</ng-template>  

组件的TS

import { Component, ViewChild, OnInit } from '@angular/core';
import { NgbCarousel, NgbSlideEvent, NgbSlideEventSource } from '@ng-bootstrap/ng-bootstrap';
import { ImageService } from 'src/app/services/image.service';
import { from } from 'rxjs';


@Component({
  selector: 'app-hardwood-heb',
  templateUrl: './hardwood-heb.component.html',
  styleUrls: ['./hardwood-heb.component.css'],

})
export class HardwoodHebComponent implements OnInit {

  public images: string[] = new Array<string>();
  public imageNames: string[] = new Array<string>();
  unpauseOnArrow: boolean = false;
  paused: boolean = false;
  pauseOnHover: boolean = true;

  constructor(private imageService: ImageService) {

  }
  ngOnInit() {
    this.images=[];
    this.imageNames = this.imageService.getImageName();
    this.images = this.imageService.getHardwoodImagesPath();
    this.images.forEach(element => {
      console.log(element);
    });

  }




  @ViewChild('carousel', { static: true }) carousel: NgbCarousel;

  togglePaused() {
    if (this.paused) {
      this.carousel.cycle();
    } else {
      this.carousel.pause();
    }
    this.paused = !this.paused;

  }

  onSlide(slideEvent: NgbSlideEvent) {
    if (this.unpauseOnArrow && slideEvent.paused &&
      (slideEvent.source == NgbSlideEventSource.ARROW_LEFT || slideEvent.source == NgbSlideEventSource.ARROW_RIGHT)) {
      this.togglePaused();
    }
    if (!slideEvent.paused && slideEvent.source == NgbSlideEventSource.INDICATOR) {
      this.togglePaused();
    }
  }

}

型号

export class Hardwood {
    public readonly name: Array<string> = ['אגוז אפריקאי','אגוז אמריקאי','אורן קרולינה','אורן קליר','אלון אדום אמריקאי',
    'אלון לבן אמריקאי','אלון אירופאי','בוק מוקצע','מייפל הארד','ספלי מהגוני','פופלר','דובדבן \ שרי','אשה'];
    // Altname uses also for path name!
    public readonly altName: Array<string> =['African Black Ofram','American Walnut','American Southern yellow pine','American Duglas fir','American Red Oak',
    'American White Oak','European Oak','European Beechwood','American Hard Maple','African Mahagoni Sapelli','American Yellow Poplar','American Cherry','American White Ash'];


}

服务

import { Hardwood } from 'src/app/models/hardwood';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ImageService {

  constructor(private hardwoods:Hardwood) { }

  public getHardwoodImagesPath():string[]{
    let str: string[] = this.hardwoods.altName;
    for ( var i = 0; i < str.length; i++ ){
      str[i] = str[i].split(' ').join('_');
      str[i] = str[i].toLocaleLowerCase();
      str[i] = `../../../assets/images/hardwoods/${str[i]}.png`;
    }
    return str;
  }

  public getImageName():string[]{
    return this.hardwoods.name; 
  }
}

【问题讨论】:

  • localhost URL 在这里不起作用 ;)
  • 将 this.imageNames 设为空数组 onInIt (this.imageNames = [])

标签: angular duplicates


【解决方案1】:

您正在修改原始数组。

您可以做的最简单的修复是使用slice 获取硬木数组的副本。这将制作一个您可以安全使用的数组副本,而无需修改原始数组。

public getHardwoodImagesPath():string[]{
  const str: string[] = this.hardwoods.altName.slice();
  for (let i = 0; i < str.length; i++) {
    str[i] = str[i].split(' ').join('_');
    str[i] = str[i].toLocaleLowerCase();
    str[i] = `../../../assets/images/hardwoods/${str[i]}.png`;
  }
  return str;
}

原因

当你这样做时:

const str: string[] = this.hardwoods.altName;

您只是将引用复制到原始数组。直接使用原始数组没有什么不同。所以当你这样做时:

str[i] = str[i].split(' ').join('_');

您实际上是在更新原始数组中的 ith 条目。

使用map

您可以通过使用数组函数map 将循环和映射组合成一个函数来改进这一点。

public getHardwoodImagesPath():string[]{
  const path = '../../../assets/images/hardwoods/';
  return this.hardwoods.altName.
    .map(x => `${path}${x.replace(/ /g, '_').toLowerCase()}.png`);
}

这是组合循环、字符串替换和新数组。这比我的第一个答案要高效得多 - 我只是想强调这个问题,而不是被其他改进分心。

【讨论】:

  • 我使用了不同的解决方案,但您帮助我理解了我的错误!非常感谢您的清晰解释!
【解决方案2】:

Kurt Hamilton 帮助我理解了我的错误。所以我做了我学到的东西(不同的方式)。现在一切正常。

  public getHardwoodImagesPath():string[]{
    let str: string[] = new Array<string>();  // Declared a new array
    for ( var i = 0; i < this.hardwoods.altName.length; i++ ){
      str[i]= this.hardwoods.altName[i]; // Get the value only..
      str[i] = str[i].split(' ').join('_');
      str[i] = str[i].toLocaleLowerCase();
      str[i] = `../../../assets/images/hardwoods/${str[i]}.png`;
    }
    return str;
  }

【讨论】:

  • 这几乎一模一样!我为我的答案添加了一个替代解决方案,它比其中任何一个都更有效。
猜你喜欢
  • 2017-11-08
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
相关资源
最近更新 更多