2016-06-30 26 views
0

我是JavaScript的新手。在這裏我想創建一個模塊來啓用自定義屬性和相關行爲。

首先,在customised.ts的開始處導入Directive和ElementRef,同時我在main.ts中導入了Jquery。因此,我有[customised.ts]僅

import {Directive, ElementRef} from '@angular/core'; 
declare var jQuery: any; 

@Directive ({ 
    selector: '[customised]' 
}) 

下面的代碼是導出類,而問題是,當我把這個。$埃爾事件監聽器函數內,這將。$ EL將是不確定的。

export class ClearInput { 
    $el: any; 

    constructor(el: ElementRef) { 
    this.$el = jQuery(el.nativeElement); 
    } 


    render():void { 
    let toggleClass = (variable) => { 
     return variable ? 'addClass' : 'removeClass'; 
    }; 

    this.$el.addClass('customised') 
    .bind('input', function() { 
     this.$el[toggleClass(this.$el.val())]('x'); 
    }) 
    .on('mousemove', function(e) { 
     if(this.$el.hasClass('x')) { // error 
     this.$el[toggleClass(this.$el.val())]('onX'); 
     } 
    }) 
    } 

    ngOnInit(): void { 
    this.render(); 
    } 
} 

的問題是:

  1. 爲什麼$ el.addClass將被執行兩次?
  2. 爲什麼這個。$ el在「if」控制流是未定義的,那麼它會拋出一個錯誤:TypeError:無法讀取屬性'hasClass'的undefined。

回答

0

這一點。$ EL是不確定的,因爲這的jQuery調用鼠標移動偵聽器時最有可能發生變化。

如果要在偵聽器中保留相同的上下文,則可以改爲使用箭頭函數。

.on('mousemove', e => { 
    if (this.$el.hasClass('x')) { 
    this.$el[toggleClass(this.$el.val())]('onX'); 
    } 
}) 

至於爲什麼addClass被執行了兩次,也許渲染功能被執行兩次?

+0

感謝。使用箭頭功能時我會小心一點。如果控制流下面的表達式是:this。$ el [toggleClass(this.offsetWidth)]('onX');那麼this.offsetWidth將無法按預期工作。這將如何改進? –

+0

好吧,我要做的一件事就是停止使用jquery。 Angular2爲您提供處理點擊元素的方法,嘗試使用這些方法。否則,你將不得不按照舊的方式使用常規函數,並將$ this.el保存在渲染中的局部變量中。 – toskv

+0

太棒了!將js代碼寫入angular2項目當然不是一個好習慣。但是,當js插件的某些以前的作品遷移到angular2時,通過使用箭頭函數分配「let self = this。$ el」可以節省大量時間。謝謝。 –

1

變化

constructor(el: ElementRef) { 
    this.$el = jQuery(el.nativeElement); 
    } 

ngAfterViewInit(el: ElementRef) { 
    this.$el = jQuery(el.nativeElement); 
    }