【问题标题】:Angular 6 refresh array and ngFor in templateAngular 6刷新数组和模板中的ngFor
【发布时间】:2019-02-14 09:07:31
【问题描述】:

我使用 angular 6,我有一个 ngbCarousel,我想通过单击按钮添加照片。

我使用ngFor 创建轮播的 HTML。

<ngb-carousel #carousel *ngIf="images">
  <ng-template ngbSlide *ngFor="let im of images; let i = index">
    <img [src]='im.link' >
    <div>
      <input type="text" value={{im.name}} >    
      <input type="text" value='description of img' >    
      <input type="text" value='copyright owners' >          
      <button type="button" (click)='deletepic(i)'>delete</button>   
    </div>
  </ng-template>
</ngb-carousel>

<button type="button" (click)='addpic()'>add</button> 
<button type="button" (click)='last()'>last</button> 

包含 JSON 的images 数组就是这个images= [{'link':'https://picsum.photos/900/500/?image=5','name':'first'},{'link':'https://picsum.photos/900/500/?image=574','name':'second'},{'link':'https://picsum.photos/900/500/?image=547','name':'third'}];,当点击addpic 时,会在数组中添加另一个 json。

 addpic(){
    this.images.push({'link':'https://picsum.photos/900/500/?image=7','name':'added one'});     
      this.last()        ;   
  }

它还必须强制轮播显示最后一张新添加的照片。根据 API,我必须使用 select 通过其 id 导航到幻灯片,并且 id 的模式为 ngb-slide-0

所以,last 包含

  last(){
    let slide = 'ngb-slide-'+String(this.images.length-1);    
    this.carousel.select(slide); 
  }

最后一张照片通常添加到轮播中

问题是从addpic 调用时last 将不起作用。即使添加了照片,它也永远不会转到最后一张照片。如果我把

let slide = 'ngb-slide-'+String(this.images.length-1);    
this.carousel.select(slide); 

addpic 中的last 仍然不起作用。它总是排到倒数第二张照片(如果我有 3 张照片,它总是排到第三张,在添加第四张之后)

但如果我点击最后一个按钮或使用轮播 UI 中的箭头,这将起作用

这让我觉得当在打字稿中调用last 时,HTML 或数组没有“刷新”,但按钮刷新/创建显示正确照片所需的 HTML?

我不知道它是什么,但我现在几乎可以肯定它与刷新 html/typescript 有关。我认为这是一个角度问题,而不是 ngbCarousel 问题。我不知道如何调试或继续。

请指教。谢谢

【问题讨论】:

    标签: angular typescript bootstrap-4 angular6 ng-bootstrap


    【解决方案1】:

    在 addpic() 方法中将图片添加到数组中后,它们需要一些时间来反映在 html 中作为模板,因此在超时时调用 last 方法,如

    addpic(){
        this.images.push({'link':'https://picsum.photos/900/500/?image=7','name':'added one'});     
        setTimeout(() => {
            this.last();
        });
      }
    

    【讨论】:

    • 所以,归结为 JS 事件循环问题。 setTimeout 是一个肮脏的黑客,我喜欢所有肮脏的黑客:) 问题是第一次被调用时,我可以看到一闪而过的空白 div 里面没有图像。
    【解决方案2】:

    您可以使用 setTimeout 在 Angular 检测到更改后强制执行 last 方法,如 Paresh Gamis 的回答。

    但我认为你也可以在这种情况下使用ChangeDetectorRef.detectChanges(),感觉不那么“hacky”。 (Documentation,以及相关问答:What's the difference between markForCheck() and detectChanges()

    在您的 last 通话之前使用它。

    我不确定它是否适用于您的情况(如果您提供 StackBlitz 最小示例,我们可以处理详细信息)

    【讨论】:

    • setTimeout 很棒,但有时会出现空转盘。关于detectChanges:听起来棒极了,但我是一个有棱角的新手,我不知道该怎么做。逻辑是什么?检测 HTML ngb-carousel 是否更改,然后调用 last ?你能否详细说明一下,我会设置一个 stockBling 或者这些天你们孩子们所说的任何东西。开个玩笑,我正在设置 StackBlitz
    • 对不起,我不知道这是空白,我在组件中导入了 ng-bootstrap、bootstrap.css 和必要的导入。 “它在我的机器上工作”。我试图找出问题所在stackBlitz
    • @selvin 我可以修复两个错误(现在我可以看到您的示例)。首先,在组件(MapcmsService)中有一条import行需要删除,并且需要在app.module.ts的imports中添加ReactiveFormsModule
    • 基本上,我只是想试试this.changeDetectorRef.detectChanges(); this.last();而不是setTimeout(() =&gt; { this.last(); });
    • 抱歉吓坏了,有一个解决办法。我可以有角度遍历ng-template ngbSlide 标签,获取最后一个,获取它的 id 并在this.carousel.select(actually_last_slide); 上使用它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2017-08-05
    • 2019-02-25
    • 2019-07-17
    • 1970-01-01
    相关资源
    最近更新 更多