首页 > 解决方案 > ElementRef 在被父组件第二次调用后失去了它的价值

问题描述

我在 Angular 5 中遇到了 ElementRef 的一个奇怪问题。我有一个包含两个弹出窗口的主组件,其中包含不同的组件 ListPopUp 和 tile。我正在遍历列表并在主页上创建多个图块。当您单击一个磁贴时,它将打开一个 listPopup。

从弹出列表中,您可以单击将触发 Parent 中的事件的函数,从而触发 tile 组件中的函数。

除了当我们第二次触发 myBar ElementRef(在 tile 组件类中)返回未定义的函数时,一切都工作文件。我尝试使用 getElementById("myBar") 直接访问该栏,但第二次它也变得未定义。我不确定为什么会发生这种情况,我试图修改代码并在 Angular 文档中寻找任何解释,但没有任何帮助。

我已经提供了所有三个组件的代码。

如果需要更多信息,请告诉我。

这是代码:

瓷砖组件:

import { Component, Input, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'tile',
  templateUrl: 'tile.html'
})
export class TileComponent {
  @Input('tileinfo') tileinfo;
  @ViewChild('myBar') myBar:ElementRef;

  constructor() {

  };

  ngOnInit() {

  };

  move(value) {
    let elem = this.myBar;
    let id = setInterval(frame, this.tileinfo.progressSpeed * 1000);
    this.tileinfo.active = value;
    let val = this.tileinfo;
    val.allowNext = false;
    function frame() {
      if (val.progress >= 100) {
        clearInterval(id);
        delete val.active;
        val.allowNext = true;
        val.progress = 0;
      } else {
        val.progress++;
        elem.nativeElement.style.width = val.progress + '%';
      }
    }
  }

}

主页组件代码:

import { Component, ViewChild } from '@angular/core';

import { GlobalProvider } from '../../providers/global/global';
import { CommonMethodsProvider } from '../../providers/common-methods/common-methods';


@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild('tileComponent') tileComponent: any;
  tileInfoArr: Array<any> = [];
  ageList: Array<any> = [];
  gameObject: any;
  modalInfo: any = {};
  modalList: any = {};
  constructor(public navCtrl: NavController, private globalService: GlobalProvider, private commonService: CommonMethodsProvider) {
    this.globalService.getGameDummy().subscribe(data => this.gameSetupHelper(data), error => console.log(error));
  }

  ngOnInit() {

  }

  fillTiles() {
    this.tileInfoArr = [
      {
        name: 'Research',
        progress: 1,
        description: "Description Here",
        progressSpeed: this.gameObject.researchProgress,
        allowNext: true,
      },
    ];
  }

  tileClicked(tileInfo) {
    switch (tileInfo.name) {
      case 'Research':
        if (this.tileInfoArr[0].allowNext)
        this.modalList = this.commonService.generateModalList("Research List", this.globalService.getAgeDataObj().researchList);
        break;
      default:
        break;
    }
  };

  listItemClicked(stuff) {
    if (stuff.data === "age") {
      this.tileComponent.move(this.gameObject.nextAgeDisplayName);
    } else {
      this.tileComponent.move(stuff.data.name);
    }
  };

}

列表弹出组件:

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'list-popup',
  templateUrl: 'list-popup.html'
})
export class ListPopupComponent {
  @Input('modalList') modalList;
  @Output() listItemClicked = new EventEmitter();

  text: string;

  constructor() {

  };

  startStuff(listItem): void {
    this.listItemClicked.emit({
      data: listItem
    });
  }

  closePopup() {
    this.modalList.showPopup = false;
  };

}

HTML:主页组件:

 <div padding style="padding-top: 0px">
    <div class="tile-container-container">
      <div class="tile-container" *ngFor="let tileinfo of tileInfoArr;">
        <tile [tileinfo]="tileinfo" (click)="tileClicked(tileinfo)" #tileComponent></tile>
      </div>
    </div>
  </div>
<info-popup [modalInfo]="modalInfo"></info-popup>
<list-popup (listItemClicked) = "listItemClicked($event)" [modalList]="modalList"></list-popup>

平铺HTML:

<div class="tile-box">
  <div class="tile-inside">
    <h6>
      {{tileinfo.name}}
    </h6>
    <p>
      {{tileinfo.description}}
    </p>
  </div>
  <footer *ngIf="tileinfo.progress !== 0">
    <div id="myProgress">
      <div id="myBar" #myBar></div>
    </div>
  </footer>
</div>

ListPopupHTML

<div *ngIf="modalList.showPopup" id="myModal" class="modal">
  <div class="modal-content card">
    <span class="close" (click)="closePopup()">
     x
    </span>
    <div>
      <h6>
        {{modalList.title}}
      </h6>
    </div>
    <hr>
    <div *ngIf="modalList.list && modalList.list.length > 0;else ageChange">
      <ul class="list">
        <li  class="item" (click)="startStuff(listInfo)" *ngFor="let listInfo of modalList.list; index as i; even as isEven; odd as isOdd" class="">
          <div>
            <span class="">{{listInfo.name}}</span>
            <br>
            <span>{{listInfo.description}}</span>
          </div>
        </li>
      </ul>
    </div>
    <ng-template #ageChange>
      <div class="age-Change">
        <h1>
          Enter New Age
        </h1>        
        <div (click)="startStuff('age')" class="new-age-icon">
        </div>
      </div>
    </ng-template>
  </div>
</div>

标签: javascriptangular

解决方案


回答我自己的问题。

最愚蠢的错误让我损失了一天的工作。

在磁贴模板中使用*ngIf="tileinfo.progress !== 0"。然后val.progress = 0;在 tileComponet 中制作。这是在最后删除 div 因此元素没有出现,因为根本没有元素。

很抱歉浪费大家的时间,谁花时间研究这个问题......


推荐阅读