Реализация директивы в Angular 4 для непрерывного циклического переключения цветов фона на хосте
Я изучаю 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>
1 ответ
Вот как вы можете это сделать:
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];
Я использую оператор по модулю %
, который возвращает остаток после целочисленного деления. Итак, он вернется:
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;
}
Или используйте круговой связанный список.
Но мне все еще не ясно, где находится моя ошибка? Это потому, что у меня есть код в основной части ngOnInit, а не функция там?
Проблема с вашим кодом не имеет ничего общего с Angular. Это то, что вы добавляете все обратные вызовы, которые будут выполнены в течение секунды. И поскольку все они выполняются очень быстро, вы видите только последнее изменение красного цвета. Вы можете исправить это так:
for (let i = 0; i < 7; i++) {
console.log(that.colors[i]);
setTimeout(function () {
that.bgColor = that.colors[i];
}, 1000*i+1)
^^^^^^ --------------
}
Но проблема остается, что ваш цикл выполняется только один раз, поэтому каждый обратный вызов запланирован только один раз.