在 Angular 4 中实施一个指令以在主机上连续循环背景颜色

Implementing a directive in Angular 4 to continuously cycle through background colors on host

我正在学习 angular 4 并想实现一个指令,使宿主元素的背景颜色循环显示数组中列出的 7 个颜色。理想情况下,我希望它是连续的。我不知道我需要挂接到哪个生命周期挂钩。 这就是我现在所拥有的。目前,它甚至 可见 以一秒的间隔循环 7 一次,正如使用 SetTimeOut 所预期的那样。我已经注释掉 While 块,因为它只会挂起浏览器。

import {
  Directive,
  OnInit,
  HostBinding,
  Input
} from '@angular/core';


@Directive({
  selector: '[rainbowize]'
})
export class RainbowizeDirective {
  colors: Array<string>;

 @HostBinding('style.backgroundColor') bgColor: string;

  constructor() {
    this.colors = ['violet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red'];
 }

 ngOnInit(){
   let that = this;
   //while (true) {
      for (let i = 0; i < 7; i++) {
        console.log(that.colors[i]);
        setTimeout(function () {
          that.bgColor = that.colors[i];
        }, 1000)
      }
    //}
  }
}

html:

<h2 rainbowize >This is a raibowized paragraph</h2>

以下是您的操作方法:

ngOnInit() {
    let that = this;
    let counter = 0;
    let length = this.colors.length;

    upd();

    function upd() {
        that.bgColor = that.colors[counter % length];
        counter++;

        // some stopping condition here
        if (counter < 20) {
            setTimeout(upd, 1000);
        }
    }
}

这里最重要的是这一行:

that.colors[counter % length];

我使用模运算符 %,它 return 是整数除法后的余数。所以它将 return:

0%7 = 0
1%7 = 1
2%7 = 2
...
6%7 = 6
7%7 = 0  <---- here the sequence starts from the beginning
8%7 = 1

这将 运行 直到 counter 变量达到 Number.MAX_SAFE_INTEGER,即 9007199254740991

另一种更简单的方法是执行以下操作:

    that.bgColor = that.colors[counter % length];
    counter++;

    if (counter === length) {
        counter = 0;
    }

或者使用循环链表

But I'm still not clear as to where my error lies? Is it because I have my code in the ngOnInit's main body as opposed to having it a function there?

您的代码问题与 Angular 无关。这是您要添加要在一秒钟内执行的所有回调。而且由于它们都执行得非常快,所以您只会看到最新的更改为红色。您可以这样修复它:

  for (let i = 0; i < 7; i++) {
    console.log(that.colors[i]);
    setTimeout(function () {
      that.bgColor = that.colors[i];
    }, 1000*i+1)
       ^^^^^^ --------------
  }

但现在的问题仍然是你的循环只执行一次,所以每个回调只安排一次。