Ошибка Angular не удается прочитать свойство ‘style’ неопределенного

#angular #typescript

#угловой #typescript

Вопрос:

Я пытаюсь преобразовать версию следующего слайд-шоу на JavaScript для использования на языке Typescript, но столкнулся с проблемой:

Я получаю сообщение об ошибке, в котором говорится:

Не удается прочитать свойство ‘style’ неопределенного

Похоже, что оно не принимается slides[this.selectedindex - 1].style.display в typescript. Итак, я добавил (<HtmlElement>...) , но это не работает.

Я реализовал следующий код:

home.component.ts

 import { Component, OnInit, ViewChild } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { NgbCarousel, NgbSlideEvent, NgbSlideEventSource } from '@ng-bootstrap/ng-bootstrap';

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

})
export class HomeComponent implements OnInit {
  title: string;
  description: string;
  role: Number;
  public selectedindex: number = 0;
  public images = ['../../assets/images/healthimage1.png', '../../assets/images/healthimage2.jpg', '../../assets/images/healthimage3.jpg'];
  
  selectImage(index: number) {
    console.log("Index: "   index);
    this.selectedindex = index;
    console.log("Selected Index: "   this.selectedindex);
  }

  showSlides() {
    let i;
    let slides = document.getElementsByClassName("mySlides");
    let dots = document.getElementsByClassName("dot");
    for (i = 0; i < slides.length; i  ) {
      (<HTMLElement>slides[i]).style.display = "none";
    }
    this.selectedindex  ;
    if (this.selectedindex > slides.length) { this.selectedindex = 1 }
    for (i = 0; i < dots.length; i  ) {
      dots[i].className = dots[i].className.replace(" active", "");
    }
    (<HTMLElement>slides[this.selectedindex - 1]).style.display = "block";
    dots[this.selectedindex - 1].className  = " active";
    setTimeout(this.showSlides, 2000);
  }


  constructor(
    private activatedRoute: ActivatedRoute,
    private router: Router) {
    this.role = 1;

  }

  ngOnInit() {
      this.showSlides();
  }

}
 

home.component.html

 <div *ngIf="images">
  <div class="mySlides slideshow-container">
      <img *ngFor="let image of images; let i=index" 
          [src]="image" 
          [ngClass]="{'image-active': selectedindex == i}">  

      <div style="text-align:center; display:inline-block;"  *ngFor="let dot of images; let i=index">
          <span class="dot" 
              (click)="selectImage(i)"
              [ngClass]="{'active': selectedindex == i}">
          </span>
      </div>
  </div>
</div>
 

css:

 .slideshow-container {
  max-width: 1200px;
  position: relative;
  margin: auto;
  text-align:center;
}

.slideshow-container img{
  display: none;
}

.slideshow-container img.image-active {
    display: block;
    width: 100%;
}

/* The dots/indicators */
.dot {
  cursor: pointer;
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.6s ease;
}

.active, .dot:hover {
  background-color: #717171;
}
 

Ответ №1:

рабочая демонстрация в этой ссылке stackblitz

Вам нужно ссылаться на html-элемент в angular, чтобы манипулировать dom в angular.

html-шаблон

 <ng-container>
<h2>Automatic Slideshow</h2>
<p>Change image every 2 seconds:</p>

<div class="slideshow-container">

    <div #slides class="mySlides fade">
        <div class="numbertext">1 / 3</div>
        <img src="https://images.pexels.com/photos/6027869/pexels-photo-6027869.jpeg" style="width:100%">
        <div class="text">Caption Text</div>
    </div>

    <div #slides class="mySlides fade">
        <div class="numbertext">2 / 3</div>
        <img src="https://images.pexels.com/photos/3889926/pexels-photo-3889926.jpeg?auto=compressamp;cs=tinysrgbamp;dpr=1amp;w=500" style="width:100%">
        <div class="text">Caption Two</div>
    </div>

    <div #slides class="mySlides fade">
        <div class="numbertext">3 / 3</div>
        <img src="https://images.pexels.com/photos/6027869/pexels-photo-6027869.jpeg" style="width:100%">
        <div class="text">Caption Three</div>
    </div>

</div>
<br>

<div style="text-align:center">
    <span #dot class="dot"></span>
    <span #dot class="dot"></span>
    <span #dot class="dot"></span>
</div>
</ng-container>
 

выше #слайды и #точки являются ссылочной переменной шаблона. Мы используем @ViewChildren(), чтобы получить более одной ссылки на элементы слайдов и точек из файла component.ts

файл component.ts

 slidesIndex = 0;
@ViewChildren("slides") slides: QueryList<ElementRef>;
@ViewChildren("dot") dots: QueryList<ElementRef>;
slider$;

ngAfterViewInit() {
  this.showSlides();
}

showSlides() {
  this.slides.forEach(
   (slidesDiv: ElementRef) =>
     (slidesDiv.nativeElement.style.display = "none")
   );
this.slidesIndex  = 1;

if (this.slidesIndex > this.slides.length) {
  this.slidesIndex = 1;
}
this.dots.forEach(
  dotsDiv =>
    (dotsDiv.nativeElement.className = dotsDiv.nativeElement.className.replace(
      " active",
      ""
    ))
);
this.slides.toArray()[this.slidesIndex - 1].nativeElement.style.display =
  "block";
this.dots.toArray()[this.slidesIndex - 1].nativeElement.className  =
  " active";
setTimeout(() => {
  this.showSlides();
}, 2000); // Change image every 2 seconds
}
 

Комментарии:

1. Вау, это отлично работает, единственная загвоздка в том, что часть этого кода я никогда раньше не видел. Вы удалили implements OnInit и использовали ngAfterViewInit вместо ngOnInit . Я заметил, что он выдал мне ошибку для функции forEach цикла with ngOnInit . Не совсем уверен, что что-то slider$; делает.

2. Мы используем @ViewChildren() .. Чтобы получить ссылку на это, доступно только в ngAfterViewOnit() . Это событие срабатывает только после того, как представление компонента отображается angular и доступно внутри файла компонента. В ngOnOnit() мы не можем получить какие-либо элементы представления внутри компонента.

3. Если у вас есть какие-либо дополнительные вопросы, не стесняйтесь обращаться ко мне по электронной почте: grdtechlab@gmail.com .

Ответ №2:

Вы пробовали использовать ViewChild, а не document.getElementByClassName.

Итак, укажите и идентификатор в html для вашего раздела слайда.

  <div class="mySlides slideshow-container" id="idSlides">
 

В вашем угловом компоненте вы определяете слайды как

 @ViewChild('idSlides', { static: false })
    slides: Slides;
 

Я думаю, значение slides не должно быть null или undefined .

Document.getElementById используется для Javascript, а не для angular

Ответ №3:

После перехода с Angular 12 на 13 у меня возникла аналогичная ошибка, потому что мы использовали пользовательский веб-пакет в angular.json. Помогло удаление и использование конфигурации сборки по умолчанию.

"builder": "@angular-builders/custom-webpack:browser", Для

"builder": "@angular-devkit/build-angular:browser",

например