Angular 6 обновить массив и ngFor в шаблоне

Я использую 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> 

Массив images, содержащий JSON, является этим 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 для перехода к слайду по его идентификатору, а идентификатор имеет шаблон ngb-slide-0.

Итак, last содержит

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

Последняя фотография обычно добавляется в карусель

Эта проблема заключается в том, что last не будет работать при вызове с addpic. Он никогда не переходит к последней фотографии, даже если фотография добавлена. Если я поставлю

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

last в addpic по-прежнему работать не будет. Он всегда переходит к предпоследней фотографии (если у меня 3 фотографии, он всегда переходит к третьей после добавления четвертой)

Но это буду работать, если я нажму последнюю кнопку или использую стрелки в пользовательском интерфейсе карусели.

Это заставляет меня думать, что каким-то образом HTML или массив не «обновляются» при вызове last в машинописном тексте, но каким-то образом кнопки обновляют / создают HTML-код, необходимый для отображения правильной фотографии?

Я не знаю, что это такое, но теперь я почти уверен, что это связано с обновлением html / typescript. Я думаю, что это угловая проблема, а не проблема ngbCarousel. Я не знаю, как отлаживать или продолжать.

Пожалуйста посоветуй. Спасибо

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
4
0
2 603
2

Ответы 2

После добавления изображения в массив в методе addpic () им требуется немного времени для отражения в html в качестве шаблона, поэтому вызовите последний метод по истечении времени ожидания, например

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

Итак, все сводится к проблеме цикла событий JS. setTimeout - это грязный хакер, и я люблю его, как и все грязные хаки :) Проблема в том, что при первом вызове я вижу вспышку пустого div без изображения внутри.

slevin 10.09.2018 13:13

Вы можете использовать setTimeout для принудительного выполнения метода last после того, как изменения были обнаружены Angular, как в ответе Пареша Гамиса.

Но я думаю, что вы также могли бы использовать ChangeDetectorRef.detectChanges() в этой ситуации, он кажется менее "хакерским". (Документация и связанные вопросы и ответы здесь: В чем разница между markForCheck () и detectChanges ())

используйте его непосредственно перед вызовом last.

Я не уверен, сработает ли это в вашем случае (если вы предоставите минимальный пример StackBlitz, мы могли бы поработать над деталями)

setTimeout великолепен, но иногда дает вспышку пустой карусели. О detectChanges: звучит круто, но я новичок в Angular и понятия не имею, что делать. В чем логика? Определить, был ли изменен HTML ngb-carousel, а затем вызвать last? Не могли бы вы рассказать подробнее, и я создам фондовый рынок или как вы, ребята, сейчас это называете. Шучу, я устанавливаю StackBlitz
slevin 10.09.2018 13:23

Извините, я не понимаю, что это пустое поле, я импортировал ng-bootstrap, bootstrap.css и необходимый импорт в компонент. «Это работает в моей машине». Я пытаюсь разобраться, что не так stackBlitz

slevin 10.09.2018 13:50

@selvin есть две ошибки, которые я могу исправить (и теперь я вижу ваш пример). Во-первых, есть строка импорта, которую вам нужно удалить в компоненте (MapcmsService), и вам нужно добавить ReactiveFormsModule в импорт app.module.ts

Pac0 10.09.2018 14:05

Теперь я застрял, я не могу добавлять фотографии (кажется, stackblitz не любит picsum.photos? Или это моя сетевая корпорация сейчас возится с HTTPS?)

Pac0 10.09.2018 14:08

в принципе, я просто хотел попробовать this.changeDetectorRef.detectChanges(); this.last(); вместо setTimeout(() => { this.last(); });

Pac0 10.09.2018 14:11

У меня плохие новости. Когда вы удаляете фотографию, а затем добавляете новую, я думаю, идентификаторы ngb-slide-XX сбиваются, и я снова оказываюсь на предпоследней фотографии !!!! Это выходит из под контроля. Есть ли способ просто показать последнее фото? Что меня расстраивает, так это то, что у меня есть простой массив, и я не могу заставить angular просто перейти к его концу и каким-то образом отобразить то, что находится внутри. Я не могу сейчас ни о чем думать, если у вас есть совет, это было бы здорово. В противном случае я не знаю. Думаю, я открою вопрос о ng-bootstrap. У меня нет времени на создание собственной галереи ...

slevin 10.09.2018 14:26

Извините за волнение, решение есть. Я могу выполнить угловой обход тега ng-template ngbSlide, получить последний тег, получить его идентификатор и использовать его на this.carousel.select(actually_last_slide);. Работая над ним.

slevin 10.09.2018 14:52

Другие вопросы по теме