【问题标题】:Angular Load Image without (click) function没有(点击)功能的角度加载图像
【发布时间】:2019-11-14 14:50:27
【问题描述】:

我正在使用 * ngFor 从 html 中的图像加载数据。

为了加载图片,需要执行另一个函数,该函数需要在 * ngFor 中加载的 ID,以查找具有该 ID 的图片。

为了获取图片,我在传递产品 ID 的地方使用了(点击),但目标是在不使用点击的情况下加载图片,即自动加载。

我有什么

HTML

 <div class="row tab-pane Galeria">
        <div *ngFor="let product of products" class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
          <div class="image-item" (click)="fillModal($event, product)">
              <a class="d-block image-block h-100">
              <homeImage> 
                    <img *ngIf [src]="Images" class="Images img-fluid" alt="">                  
              </homeImage> 
              </a>           
            <div class="ImageText" (click)="ImageInfo(product.id)">{{product.name}}</div>
          </div>
        </div>
      </div>

Component.ts

ngOnInit() {
    this.GetProducts();
  }

  GetProducts() {
    let self = this;
    this.Global.refreshToken().subscribe(function (result) {
      self.homeService.getProducts().then(function (resultado) {
        if (resultado) {
         self.products = resultado;
        }
      }).catch();
    }); 
  }


  ImageInfo(id) {
      var self = this;
      self.Global.refreshToken().subscribe(function (result) {
        self.homeService.getImage(id).then(function (resultado) {
          if (resultado) {
            self.Images = resultado;
          }
        }).catch();
      });
    }

Service.ts

getProducts(): Promise<any> {
    let self = this;
    let urlAux = self.url + "/Products/GetProducts";
    return axios.get(urlAux, {
      headers: {
        Authorization: 'Bearer ' + localStorage.getItem("access_token")
      }
    })
      .then(this.extraData)
      .catch(this.handleErroPromisse);
  }

  getImage(id): Promise<any> {
    let self = this;
    let urlAux = self.url + "/Products/GetImage/" + id;

    return axios.get(urlAux, {'responseType': 'arraybuffer'})
      .then((response) => {
        let image = btoa(
          new Uint8Array(response.data)
            .reduce((data, byte) => data + String.fromCharCode(byte), '')
        );
        return `data:${response.headers['content-type'].toLowerCase()};base64,${image}`;
      });
  }

我测试过但没用的:

在 src 中执行函数不起作用:(

 <div class="row tab-pane Galeria">
        <div *ngFor="let product of products" class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
          <div class="image-item" (click)="fillModal($event, product)">
              <a class="d-block image-block h-100">
              <homeImage> 
                    <img *ngIf [src]="ImageInfo(product.id)" class="Images img-fluid" alt="">                  
              </homeImage> 
              </a>           
            <div class="ImageText">{{product.name}}</div>
          </div>
        </div>
      </div>

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    您正在执行的操作是异步的(它返回一个 Promise)。

    这就是为什么您需要确保将属性标记为等待异步操作,或者使操作“不那么异步”:-)。

    预先进行处理

    如果您立即解析打字稿中的图像,您可以跳过函数的异步部分并在 component.ts 文件中执行相同的操作。

    组件.ts

    ngOnInit() {
      this.GetProducts();
    }
    
    GetProducts() {
      let self = this;
      this.Global.refreshToken()
        .subscribe(function (result) {
          self.homeService.getProducts()
            .then(function (resultado) {
              if (resultado) {
                self.products = resultado;
              }
            })
            .then(() => {
              if (self.products) {
                return Promise.all(self.products.map((product) => self.ImageInfo(product.id)));
              }
            })
            .catch((err) => console.error(err));
        });
    }
    
    
    ImageInfo(id) {
      var self = this;
      self.Global.refreshToken().subscribe(function (result) {
        self.homeService.getImage(id).then(function (resultado) {
          if (resultado) {
            // self.Images = resultado;
    
            self.images[id] = resultado; // <-- changed to id so you can fetch easily
          }
        }).catch();
      });
    }
    

    HTML

     <div class="row tab-pane Galeria">
      <div *ngFor="let product of products" class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
        <div class="image-item" (click)="fillModal($event, product)">
            <a class="d-block image-block h-100">
            <homeImage> 
                  <img *ngIf="images[product.id]" [src]="images[product.id]" class="Images img-fluid" alt="">                  
            </homeImage> 
            </a>           
          <div class="ImageText">{{product.name}}</div>
        </div>
      </div>
    </div>
    

    现在,如果我们在获取产品时已经获取了数据,我只是显示图像。这样,异步操作发生在 component.ts 中,HTML 保持同步。

    这两种解决方案的主要区别在于是否要使用prefetching

    【讨论】:

    • 第一个,不起作用,进入死循环。第二个解决方案太接近工作了,我只是得到错误:无法读取属性'1009' of undefined at line
    • 这是唯一接近解决方案的人,我真的很感激,我留下了我的贡献
    • @John 1st 不起作用,因为您的函数不返回任何内容。如果你使用[src]="ImageInfo(product.id) | async" async 与否...函数必须返回一些东西,在异步情况下是Promise&lt;string&gt;,在同步情况下是string。在您的情况下,它返回未定义。
    • 对不起,但没有意识到,即使这个错误消失,我应该改变什么?我用我的 service.ts 更新了帖子
    • 示例 1 不起作用,将函数放入 src 停止工作。我发布了这个但得到了同样的错误 跨度>
    【解决方案2】:

    它不起作用,因为您的 ImageInfo(id) 没有返回任何可以分配给 img src 的内容。它加载图像信息并将结果存储到this.Images。但是在模板中,你将函数的返回值绑定到src

    您可能想要做的是在 ngOnInit 中加载所有产品,然后为所有产品加载所有 ImageInfos(假设您的 API 是这样工作的......)

    类似:

    async ngOnInit() {
        this.products = await this.service.loadProducts();
        for (const p of this.product) {
           this.images[p.id] = await this.imageService.getInfo(p.id));
        }
    }
    

    <div *ngFor="let product of products">
      <img *ngIf="images[product.id]" [src]="images[product.id].src" > 
    </div>
    

    【讨论】:

    • 我收到此错误:无法在
    • @John 在构造函数中初始化images 或添加*ngIf="images &amp;&amp; images[product.id]
    猜你喜欢
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多