WedX - журнал о программировании и компьютерных науках

как реализовать слайдер с несколькими элементами в angular?

я пытаюсь реализовать слайдер с несколькими элементами в angular 7. Он отлично работает, когда я использую статические данные в html, но когда я пытаюсь реализовать то же самое динамически из angular с помощью ngFor, то на первой странице это не показывает что угодно, но когда я перехожу к следующему слайду, он работает нормально.

это код со статическими данными в html

HTML: -

<div class=" container-fluid news-slider">
      <div class="row mySlides fad">
            <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem">
                <mat-card class="insidecard newscard">
                    <img mat-card-image src="../../assets/img/download.jpg" class="newsimage">
                    <mat-card-content>
                        <div class="newsdetails">
                          The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
                          A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
                          bred for hunting.
                        </div>
                      </mat-card-content>
                </mat-card>
              </div>
              <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem">
                  <mat-card class="insidecard newscard">
                      <img mat-card-image src="../../assets/img/download.jpg" class="newsimage">
                      <mat-card-content>
                          <div class="newsdetails">
                            The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
                            A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
                            bred for hunting.
                          </div>
                        </mat-card-content>
                  </mat-card>
                </div>
                <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem">
                    <mat-card class="insidecard newscard">
                        <img mat-card-image src="../../assets/img/download.jpg" class="newsimage">
                        <mat-card-content>
                            <div class="newsdetails">
                              The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
                              A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
                              bred for hunting.
                            </div>
                          </mat-card-content>
                    </mat-card>
                  </div>
                  <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem">
                      <mat-card class="insidecard newscard">
                          <img mat-card-image src="../../assets/img/download.jpg" class="newsimage">
                          <mat-card-content>
                              <div class="newsdetails">
                                The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
                                A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
                                bred for hunting.
                              </div>
                            </mat-card-content>
                      </mat-card>
                    </div>
                    <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem">
                        <mat-card class="insidecard newscard">
                            <img mat-card-image src="../../assets/img/download.jpg" class="newsimage">
                            <mat-card-content>
                                <div class="newsdetails">
                                  The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
                                  A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
                                  bred for hunting.
                                </div>
                              </mat-card-content>
                        </mat-card>
                      </div>
                      <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem">
                          <mat-card class="insidecard newscard">
                              <img mat-card-image src="../../assets/img/download.jpg" class="newsimage">
                              <mat-card-content>
                                  <div class="newsdetails">
                                    The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
                                    A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
                                    bred for hunting.
                                  </div>
                                </mat-card-content>
                          </mat-card>
                        </div>


          </div>
        <a class="pre" (click)="plusSlides(-1)">&#10094;</a>
        <a class="nex" (click)="plusSlides(1)">&#10095;</a>
  </div>


CSS:-


.news-slider{
    position: relative;
}
.mySlides{
    display: none;
}
.pre,.nex{
    cursor: pointer;
    position: absolute;
    top:50%;
    width: auto;
    padding: 16px;
    margin-top: -22px;
    color:red;
    font-weight: bold;
    font-size: 18px;
    transition: 0.6s ease; 
    border-radius: 0 3px 3px 0;
    user-select: none;
    background-color:white;
    box-shadow: 1px 2px 10px -1px rgba(0,0,0,.3);
}
.nex {
    right: 0;
    border-radius: 3px 0 0 3px;
    margin-right: 0px;
  } 
  .pre{
    margin-left:-15px;
  }
   .fad {
    -webkit-animation-name: fade;
    -webkit-animation-duration: 1.5s;
    animation-name: fade;
    animation-duration: 1.5s;
  }



Angular:-


export class MainpageComponent implements OnInit {
  slideIndex = 1;

  parent = document.getElementsByClassName("mySlides");

   constructor(config : NgbCarouselConfig,public httpclient:HttpClient,private renderer:Renderer2) {
    config.interval = 2000;
    config.wrap = true;
    config.keyboard = false;
    config.pauseOnHover = true;
   }

  ngOnInit() {
    this.showSlides(this.slideIndex);
  }

 showSlides(n)
  {
      var i;
      if(n>this.parent.length)
      {
        this.slideIndex = 1;
      }
      if(n<1)
      {
        this.slideIndex = this.parent.length;
      }
      for(i=0;i<this.parent.length;i++)
      {
        this.renderer.setStyle(this.parent[i],'display','none');
      }
      this.renderer.setStyle(this.parent[this.slideIndex-1],'display','flex');
      console.log(this.parent[0]);
  }
  plusSlides(n)
  {
    this.showSlides(this.slideIndex += n);
  }

}

это код, который я использовал для динамического отображения

HTML:-
```
<div class=" container-fluid news-slider">
      <div class="row mySlides fad" *ngFor="let newsarray of newschunk">
          <div class=" col-xl-2 col-lg-2 col-md-2 col-sm-2 newsitem" *ngFor="let item of newsarray">
              <mat-card class="insidecard newscard">
                <img mat-card-image [src]="item.img" class="newimage">
                <mat-card-content>
                    <div class="newsdetails">
                      {{item.description}}
                    </div>
                  </mat-card-content>
              </mat-card>
            </div>

          </div>
        <a class="pre" (click)="plusSlides(-1)">&#10094;</a>
        <a class="nex" (click)="plusSlides(1)">&#10095;</a>
  </div>


CSS:-

.news-slider{
    position: relative;
}
.mySlides{
    display: none;
}
.pre,.nex{
    cursor: pointer;
    position: absolute;
    top:50%;
    width: auto;
    padding: 16px;
    margin-top: -22px;
    color:red;
    font-weight: bold;
    font-size: 18px;
    transition: 0.6s ease; 
    border-radius: 0 3px 3px 0;
    user-select: none;
    background-color:white;
    box-shadow: 1px 2px 10px -1px rgba(0,0,0,.3);
}
.nex {
    right: 0;
    border-radius: 3px 0 0 3px;
    margin-right: 0px;
  } 
  .pre{
    margin-left:-15px;
  }
   .fad {
    -webkit-animation-name: fade;
    -webkit-animation-duration: 1.5s;
    animation-name: fade;
    animation-duration: 1.5s;
  }


ANGULAR:-

export class MainpageComponent implements OnInit {
  slideIndex = 1;

  parent = document.getElementsByClassName("mySlides");


  public newsdata = [
    {
      title: 'Card Title 1',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 2',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 3',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 4',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 5',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 6',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 7',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 8',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
    {
      title: 'Card Title 9',
      description: 'Some quick example text to build on the card title and make up the bulk of the card content',
      buttonText: 'Button',
      img: 'https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20(34).jpg'
    },
  ];
  public newschunk:any=[[]];

  constructor(config : NgbCarouselConfig,public httpclient:HttpClient,private renderer:Renderer2) {
    config.interval = 2000;
    config.wrap = true;
    config.keyboard = false;
    config.pauseOnHover = true;
   }

  ngOnInit() {
    //this.changecol.send("yes");

    this.getTopNews();
    //console.log(this.newsdiv);
    //console.log(this.parent[0]);   

  }


  showSlides(n)
  {
      var i;
      if(n>this.parent.length)
      {
        this.slideIndex = 1;
      }
      if(n<1)
      {
        this.slideIndex = this.parent.length;
      }
      for(i=0;i<this.parent.length;i++)
      {
        this.renderer.setStyle(this.parent[i],'display','none');
      }
      this.renderer.setStyle(this.parent[this.slideIndex-1],'display','flex');
      console.log(this.parent[0]);
  }
  plusSlides(n)
  {
    this.showSlides(this.slideIndex += n);
  }
  getTopNews() {
    this.httpclient.get<{message:any,errorMessage:string}>("https://localhost:3000/trendingNews").subscribe((responsedata)=>{
      //this.newsdata=responsedata.message;
      this.newschunk = this.getChunks(this.newsdata,6);
      this.showSlides(this.slideIndex);
  },(error)=>{
    console.log(error);
    this.renderer.setStyle(this.newsdiv[0],'display','none');

  });
  }

  getChunks(arr,size)
  {
    let chunkarray = [];
    for(let i=0;i<arr.length;i+=size)
    {
      chunkarray.push(arr.slice(i,i+size));
    }
    return chunkarray;
  }

}


1st image with static data in html

2nd image with dynamic data from angular without sliding

3rd image when i click the next arrow 

Поведение: image 3 изображение 2 image 1


Ответы:


1

у вас было 2 вещи:

  1. Получить данные в Newschuck
  2. Показать слайды

Проблема № 1: вы выполнили обе эти задачи в ngOnInit — выборка данных (пункт № 1) в OnInit работает нормально, но отображение слайдов (пункт № 2) не сработает, поскольку ngOnInit запускается до страница отображается.

Проблема № 2: если вы поместили оба эти пункта (пункт № 1 и № 2) в ngAfterViewInit — вы получите сообщение об ошибке «выражение изменилось после проверки…»

Решение: получить данные (точка №1) в OnInit; отображать слайды (пункт №2) после рендеринга страницы. Для этого я создал логическую переменную (это поможет, если вы получаете данные из остальных API).

проверьте полную демонстрацию из вашего gitib здесь

EDIT (1). Чтобы сделать это с помощью rest API, перенесите код, который у вас был внутри ngAfterViewInit, в блок finally () => { }, как показано ниже:

  getTopNews() { this.httpclient.get<{ message: any, errorMessage: string }>("localhost:3000/trendingNews").subscribe(
    responsedata => { this.newsdata = responsedata.message; 
    this.newschunk = this.getChunks(this.newsdata, 3);
    this.arrayUpdated = true;
    }
    ,error => { console.log(error); this.renderer.setStyle(this.newsdiv[0], 'display', 'none'); });
    /* this is the finally block */
    () =>{     if (this.arrayUpdated) {      this.showSlides(this.slideIndex);     }}
    }
29.04.2019
  • Он отлично работает, когда я даю статический массив в angular, но он работает так же, как и раньше, когда я получаю массив из базы данных. 29.04.2019
  • да, я понимаю, когда я даю статические данные 29.04.2019
  • getTopNews() { this.httpclient.get‹{message:any,errorMessage:string}›(localhost:3000/trendingNews).subscribe((responsedata)=›{ this.newsdata=responsedata.message; this.newschunk = this.getChunks(this.newsdata, 3); this.arrayUpdated = true; это .newssmall = this.newsdata.slice(0,4);},(ошибка)=›{ console.log(ошибка); this.renderer.setStyle(this.newsdiv[0],'display','none') ; }); } 29.04.2019
  • когда я делаю что-то подобное, он работает так же, как и раньше, не показывая первую страницу 29.04.2019
  • вы испытываете это, потому что ngAfterViewInit срабатывает до того, как вы получили результат от rest-api... проверьте изменения кода в коде в ответе 29.04.2019
  • getTopNews() { this.httpclient.get‹{message:any,errorMessage:string}›(localhost:3000/trendingNews).subscribe((responsedata)=›{ this.newsdata=responsedata.message; this.newschunk = this.getChunks(this.newsdata, 3); this.arrayUpdated = true; это .newssmall = this.newsdata.slice(0,4);},error =› { console.log(error); this.renderer.setStyle(this.newsdiv[0], 'display', 'none'); } ,()=›{ if (this.arrayUpdated) { this.showSlides(this.slideIndex); } }); } 29.04.2019
  • console.log(this.parent[0]) я получаю это при первой загрузке ‹!--bindings={ ng-reflect-ng-for-of: } --› я получаю это, когда нажимаю следующую стрелку ‹! --bindings={ ng-reflect-ng-for-of: [object Object],[object Object }--› 29.04.2019
  • Я назначаю родителя с помощью document.getElementsByClassName(mySlides); в начале нормально? 29.04.2019
  • можете ли вы внести изменения в этот код github.com/suhail-1997/multisliderangular 29.04.2019
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]