setInterval() 问题不访问 Angular2 中的指令函数
Issue with setInterval() not accessing directive function in Angular2
我正在尝试制作一个新闻代码指令,将元素滑过其父元素,以便您可以在字符串太长时读取它。我被卡住了,因为我无法让 setInterval()
函数在其当前范围内调用 moveLeft()
函数,从而将目标元素 (this.node1
) 移动到 1px
.如果我将元素、函数和参数传递给 setInterval()
,则不会调整 DOM,因为我认为该元素超出范围。 如何从 setInterval()
函数调用其当前作用域中的 moveLeft()
函数? 该函数在 setInterval()
函数外部调用时工作正常。
import { Directive, ElementRef, HostListener, Input, Renderer, OnInit } from '@angular/core';
@Directive({ selector: '[ticker]' })
export class TickerDirective implements OnInit {
currMargin: number; // i.e.: 4
newMargin: string; // i.e.: '4px'
currInterval: any; // timeout function variable used to kill the timeout
container: any; // container element
node1: any;
node2: any;
tickerNodes: any[];
textValue: string;
@Input('text') text: string; // display string passed in on an attribute
constructor(private el: ElementRef, private renderer: Renderer) { }
@HostListener('mouseenter') onMouseEnter() {
// this is where the script is failing
this.currInterval = setInterval( this.moveLeft(), 100);
}
@HostListener('mouseleave') onMouseLeave() {
clearInterval(this.currInterval);
this.currMargin = 0;
}
moveLeft() { // slide the elements to the left
this.currMargin -= 1;
this.newMargin = this.currMargin + 'px';
this.renderer.setElementStyle(this.node1, 'margin-left', this.newMargin);
}
ngOnInit() { // instantiate the elements
this.currMargin = 0;
this.textValue = this.el.nativeElement.attributes[2].nodeValue; // sets the text value passed from the component to the directive through an attribute
// build the container
this.container = this.renderer.createElement(this.el.nativeElement, 'div');
this.renderer.setElementClass(this.container, 'ticker-container', true);
// create the left most element
this.node1 = this.renderer.createElement(this.container, 'div');
this.renderer.setElementClass(this.node1, 'ticker-node', true);
this.renderer.setText(this.node1, this.el.nativeElement.attributes[2].nodeValue);
// create the right most element
this.node2 = this.renderer.createElement(this.container, 'div');
this.renderer.setElementClass(this.node2, 'ticker-node', true);
this.renderer.setText(this.node2, this.el.nativeElement.attributes[2].nodeValue);
// render the elementss
this.tickerNodes = [this.node1, this.node2];
this.renderer.attachViewAfter(this.container, this.tickerNodes);
}
}
在您调用
的方法中使用 setInterval()
moveLeft() { // slide the elements to the left
setInterval(() => {
this.currMargin -= 1;
this.newMargin = this.currMargin + 'px';
this.renderer.setElementStyle(this.node1, 'margin-left', this.newMargin);
}, 100);
}
首先,在您的原始版本中,您在间隔设置期间执行 moveleft,而不是提供函数。所以它会在您设置时执行,但不会再执行。
即。 setInterval( this.moveLeft, 100)
而不是 setInterval( this.moveLeft(), 100)
但真正的问题是为 setInterval 提供一个箭头函数,而不是直接提供函数,因为简单地给它函数将改变 this
的上下文(参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
例如。 setInterval( () => { this.moveLeft(); }, 100)
我正在尝试制作一个新闻代码指令,将元素滑过其父元素,以便您可以在字符串太长时读取它。我被卡住了,因为我无法让 setInterval()
函数在其当前范围内调用 moveLeft()
函数,从而将目标元素 (this.node1
) 移动到 1px
.如果我将元素、函数和参数传递给 setInterval()
,则不会调整 DOM,因为我认为该元素超出范围。 如何从 setInterval()
函数调用其当前作用域中的 moveLeft()
函数? 该函数在 setInterval()
函数外部调用时工作正常。
import { Directive, ElementRef, HostListener, Input, Renderer, OnInit } from '@angular/core';
@Directive({ selector: '[ticker]' })
export class TickerDirective implements OnInit {
currMargin: number; // i.e.: 4
newMargin: string; // i.e.: '4px'
currInterval: any; // timeout function variable used to kill the timeout
container: any; // container element
node1: any;
node2: any;
tickerNodes: any[];
textValue: string;
@Input('text') text: string; // display string passed in on an attribute
constructor(private el: ElementRef, private renderer: Renderer) { }
@HostListener('mouseenter') onMouseEnter() {
// this is where the script is failing
this.currInterval = setInterval( this.moveLeft(), 100);
}
@HostListener('mouseleave') onMouseLeave() {
clearInterval(this.currInterval);
this.currMargin = 0;
}
moveLeft() { // slide the elements to the left
this.currMargin -= 1;
this.newMargin = this.currMargin + 'px';
this.renderer.setElementStyle(this.node1, 'margin-left', this.newMargin);
}
ngOnInit() { // instantiate the elements
this.currMargin = 0;
this.textValue = this.el.nativeElement.attributes[2].nodeValue; // sets the text value passed from the component to the directive through an attribute
// build the container
this.container = this.renderer.createElement(this.el.nativeElement, 'div');
this.renderer.setElementClass(this.container, 'ticker-container', true);
// create the left most element
this.node1 = this.renderer.createElement(this.container, 'div');
this.renderer.setElementClass(this.node1, 'ticker-node', true);
this.renderer.setText(this.node1, this.el.nativeElement.attributes[2].nodeValue);
// create the right most element
this.node2 = this.renderer.createElement(this.container, 'div');
this.renderer.setElementClass(this.node2, 'ticker-node', true);
this.renderer.setText(this.node2, this.el.nativeElement.attributes[2].nodeValue);
// render the elementss
this.tickerNodes = [this.node1, this.node2];
this.renderer.attachViewAfter(this.container, this.tickerNodes);
}
}
在您调用
的方法中使用setInterval()
moveLeft() { // slide the elements to the left
setInterval(() => {
this.currMargin -= 1;
this.newMargin = this.currMargin + 'px';
this.renderer.setElementStyle(this.node1, 'margin-left', this.newMargin);
}, 100);
}
首先,在您的原始版本中,您在间隔设置期间执行 moveleft,而不是提供函数。所以它会在您设置时执行,但不会再执行。
即。 setInterval( this.moveLeft, 100)
而不是 setInterval( this.moveLeft(), 100)
但真正的问题是为 setInterval 提供一个箭头函数,而不是直接提供函数,因为简单地给它函数将改变 this
的上下文(参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
例如。 setInterval( () => { this.moveLeft(); }, 100)