将相同的指令应用于单个组件中的多个 div,将该指令的事件侦听器仅附加到最后一个
Applying same directive to many divs in a single component, attaches event listener of that directive to only the last one
我在单个组件上有 50 个 div。我正在制作一个名为 "lazyload" 的指令。然后我将此指令应用于所有这些 divs。在 "lazyload" 指令的 onInit 中,我已经注册了滚动事件。 scroll 的 eventlistener 函数应该检查这个 div(在我的例子中,所有这些 50 divs 应用这个指令)是否在视口内,然后在那个特定的地方做一些操作div。但是这个滚动事件似乎只为我视图的最后一个 div 注册。
我的组件模板:
<div class="product-container" *ngFor="#product of allProducts">
<div class="product-image"
[lazyLoadImage]="product.image" >
</div>
<div class="product-desc">
<p>{{product.name}}</p>
<p> <span>{{product.price | currency:'INR':true}}</span> <span>{{product.monthDiff + " months"}}</span> </p>
</div>
</div>
指令"lazyLoadImage"是:
@Directive({
selector: '[lazyLoadImage]'
})
export class LazyLoadImgDirective {
private _el: HTMLElement;
private _canLoadImage: boolean = false;
private _imgUrl: string;
@Input()
set lazyLoadImage(v){
this._imgUrl = v;
if(v){
this.attachEvent()
}
}
constructor(el: ElementRef, private _utils:UtilServices) { this._el = el.nativeElement;}
private _loadingDone: boolean = false;
loadImage(){
//some operations
}
attachEvent() {
console.log("inside image load dir");
var self = this;
setTimeout(() => self.loadImage(), 1);
window.onscroll = (event) => {
console.log("scrolling intercepted for: "+self._imgUrl);//log is shown only for the last element where this directive is applied
if (!self._loadingDone){
setTimeout(() => self.loadImage(), 1);
}
}
}
}
滚动的事件侦听器仅在迭代中的最后一个产品上工作。
正如@yurzui 所说,您正在覆盖事件处理程序。
我还修复了您代码中的其他一些问题(如果您使用 =>
和其他一些问题,则不需要 self = this
)。
ElementRef
是 null
,因为 , private _utils:UtilServices
没有提供商。删除此参数会使 ElementRef
被设置。
我在单个组件上有 50 个 div。我正在制作一个名为 "lazyload" 的指令。然后我将此指令应用于所有这些 divs。在 "lazyload" 指令的 onInit 中,我已经注册了滚动事件。 scroll 的 eventlistener 函数应该检查这个 div(在我的例子中,所有这些 50 divs 应用这个指令)是否在视口内,然后在那个特定的地方做一些操作div。但是这个滚动事件似乎只为我视图的最后一个 div 注册。
我的组件模板:
<div class="product-container" *ngFor="#product of allProducts">
<div class="product-image"
[lazyLoadImage]="product.image" >
</div>
<div class="product-desc">
<p>{{product.name}}</p>
<p> <span>{{product.price | currency:'INR':true}}</span> <span>{{product.monthDiff + " months"}}</span> </p>
</div>
</div>
指令"lazyLoadImage"是:
@Directive({
selector: '[lazyLoadImage]'
})
export class LazyLoadImgDirective {
private _el: HTMLElement;
private _canLoadImage: boolean = false;
private _imgUrl: string;
@Input()
set lazyLoadImage(v){
this._imgUrl = v;
if(v){
this.attachEvent()
}
}
constructor(el: ElementRef, private _utils:UtilServices) { this._el = el.nativeElement;}
private _loadingDone: boolean = false;
loadImage(){
//some operations
}
attachEvent() {
console.log("inside image load dir");
var self = this;
setTimeout(() => self.loadImage(), 1);
window.onscroll = (event) => {
console.log("scrolling intercepted for: "+self._imgUrl);//log is shown only for the last element where this directive is applied
if (!self._loadingDone){
setTimeout(() => self.loadImage(), 1);
}
}
}
}
滚动的事件侦听器仅在迭代中的最后一个产品上工作。
正如@yurzui 所说,您正在覆盖事件处理程序。
我还修复了您代码中的其他一些问题(如果您使用 =>
和其他一些问题,则不需要 self = this
)。
ElementRef
是 null
,因为 , private _utils:UtilServices
没有提供商。删除此参数会使 ElementRef
被设置。