Angular:使用ngIf可以看到元素时的触发事件

时间:2018-05-31 06:38:02

标签: javascript angular javascript-events event-handling angular-event-emitter

我有一些使用ngIf的div,我只是想知道特定的div是否是现在可见/活动的那个像焦点这样的事件触发器(它不起作用)或者某种东西,对于这个事件,我会设置变量或其他东西。

const VideoDetail = ({video,viewCount}) => {
    return (
        <p className="views"><i className="material-icons">remove_red_eye</i>{viewCount}</p>
    );
};

4 个答案:

答案 0 :(得分:1)

触发更改检测后,您的div将呈现并可见。检测到更改后,将再次运行整个生命周期。

如果你想运行某些东西,你应该挂钩生命周期中的一个事件。我建议AfterViewInit

现在您已经知道了,让我们看看您应该做些什么。

在您的情况下,您应该使用模板引用创建div。这将允许您对元素进行引用,并使您能够检查显示或隐藏的div。

Here is a stackblitz向您展示了它的工作原理,以下是代码:

import { Component, ViewChildren, QueryList, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <div *ngFor="let item of [0, 1, 2, 3, 4, 5]; let i = index">
    <span *ngIf="i === show" #shownDiv [id]="'div-' + i">{{ item }}</span>
  </div>
  `
})
export class AppComponent {
  name = 'Angular 6';
  show = 0;

  @ViewChildren('shownDiv') divs: QueryList<ElementRef>;

  ngOnInit() {
    setInterval(() => {
      this.show++;
      if (this.show > 5) {
        this.show = 0;
      }
    }, 1000);
  }

  ngAfterViewChecked() {
    let shown = this.divs.find(div => !!div);
    console.log('DIV shown is ' + (shown.nativeElement as HTMLSpanElement).id);
    // Now that you know which div is shown, you can run whatever piece of code you want
  }
}

答案 1 :(得分:1)

这可能是一种可行的解决方法。它可能不是最好的但可行。

在html文件中,

<div *ngIf="show()"> </div>

在组件TS文件中,

show(){
  if(test){ //condition for showing the div
    myVariable = true; 
    return true;
  }
  else
    return false;
}

答案 2 :(得分:1)

一个解决方案是使用 @ViewChildren 并订阅 changesQueryListngAfterViewInit() Observable,同时避免 ExpressionChangedAfterItHasBeenCheckedError(如果例如,当 div 可见时,您想更改模板中使用的属性)您可以像这样使用 detectChanges()ChangeDetectorRef

@Component({
  selector: "my-app",
  template: `
    <div *ngIf="num % 10 === 0" #doSomethingWhenVisibleDIV>
      Show some content
    </div>
    <div *ngIf="showOtherDiv">Show different content here</div>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
  num: number = 0;
  showOtherDiv: boolean = false;

  private subscription: Subscription;

  @ViewChildren("doSomethingWhenVisibleDIV") divs: QueryList<ElementRef>;

  constructor(private changeDetectorRef: ChangeDetectorRef) {}

  ngOnInit() {
    setInterval(() => this.num++, 1000);
  }

  ngAfterViewInit() {
    this.subscription = this.divs.changes.subscribe({
      next: () => {
        if (this.divs.length > 0) {
          this.showOtherDiv = !this.showOtherDiv;
          this.changeDetectorRef.detectChanges();
        }
      }
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Stackblitz example

答案 3 :(得分:0)

我想以拉奇(Rachit)的答案为基础。

<div *ngIf="test"><ng-container *ngIf="runShow && show()"></ng-container></div>

和组件中的

this.runShow = true;

//show always returns true.
show() {
  //Return if not running. Shouldn't be needed as runShow proceeds show in the template.
  if(!this.runShow) {
    return true;
  }
  //Do modifications...

  this.runShow = false;
  return true;

show()仅在测试是真实的情况下运行,并且会在单次迭代后自动关闭(当然,您可以更改this.runShow来基于某种情况)。一个重要的陷阱是,直到this.runShow == false为止,此操作将在每次组件检测到更改时运行,且不再更改。 我们将show()放在其自己的ng-container中,以使其不影响DOM,并在呈现测试后运行。