2017-08-27 8 views
-1

Angular TypescriptファイルにJavaScriptのバージョンが混在しています。関数とこれを宣言します。 JavaScriptのバージョン

以下のコードでは、ngOnInitの関数globalNavigationHandlerは認識されず、this.globalNavigationHandlerを使用することができません。これは、保持する必要がある意味が異なるためです。

私はこのリバウンドが必要なため、矢印機能ではないイベントリスナーを持っています。

しかし、globalnavigationHandlerと呼ばれる他の関数を認識する関数を正しく取得する方法がわかりません。 globalNavigationHandlerをインラインにすることはできません。なぜなら、コンストラクタに注入され、これとは異なる意味を持つルータが必要だからです。

globalNavigationHandler = function(path) { 
    this.router.navigate([path]); 
    } 

    ngOnInit() { 
    var nav = document.getElementById("uhf-c-nav"); 
    var anchors = nav.getElementsByTagName("a"); 

    for (var i = 0; i < anchors.length; i++) { 
     anchors[i].addEventListener(
     "click", 
     function(event) { 
      event.preventDefault(); 
      console.log("this is the element the event is bound to: " + this.id); 
      console.log("the event target is the clicked element: " + event); 
      console.log("this: " + this); 
      console.log("this.pathname: " + this.pathname); 

      globalNavigationHandler(this.pathname); 
     }, 
     false 
    ); 
    } 
    } 

おかげ

+0

イベントをバインドするために 'ElementRef'と' nativeElement'プロパティを使うことができます。 – Aravind

+0

"JavaScriptバージョン"とはどういう意味ですか? –

+0

ECMAScriptの構文など。私はおそらく間違って言った。 –

答えて

0

globalNavigationHandlerそれは意味的に正しいだし、それはまだthis.routerを得るためにthis適切にバインドする必要があるため、クラスメソッドでなければなりません。クラスメソッドに到達するのに、this.globalNavigationHandlerのような問題がある場合は、別の方法で解決する必要があります。

2つのコンテキストが使用されている場合、このケースにアプローチするためのレシピがいくつかあります。これを行うには、最も人気のある簡単な方法は、変数にそれらのいずれかを割り当てている。実際には

const self = this; 
... 

    anchors[i].addEventListener(
    "click", 
    function(event) { 
     ... 
     self.globalNavigationHandler(this.pathname); 
    }, 
    false 
); 

それがコールバック発信者がthisに依存しており、コールバックですべての必要な情報を提供しないようにするために良い習慣だから、それはほとんど必要ありません議論イベントリスナーの場合は、event.targetで、上記のコードではthisと等しいです。これは、代わりに次のようになります。

anchors[i].addEventListener(
    "click", 
    event => { 
     ... 
     this.globalNavigationHandler(event.target.pathname); 
    }, 
    false 
); 

角度に自然な方法で対処すべきXYの問題であることが表示されます。通常、Angularで直接addEventListenerを使用する必要はありません。 Renderer2プロバイダーはDOM関連の操作に使用される抽象であり、hereと表示され、要素の参照はViewChild/ViewChildrenで取得される必要があります。

これらの要素を親からではなくディレクティブでクリックリスナーを設定することが可能な場合は、これが望ましいアプローチです。

+0

私は上記の自己メソッドを使い終わった。私が持っていたものから簡単かつ迅速に変更できました –

0
globalNavigationHandler(path) { 
    this.router.navigate([path]); 
} 

はこのようにそれを宣言するだけで試してみてください。

EDIT - 通常、私はより良い説明を提供します...しかし、私は 'バニラ'ジャバスクリプトで多くの経験がありません。たぶん誰か他の人がこれがなぜそうであるか説明することができます。私はちょうどこれがあなたがtypescriptでクラスの中で関数を宣言する方法であることを知っています。別の関数の中で関数を宣言しているのに、クラス関数が= assignmentとfunctionキーワードなしで宣言されている場合は、元の投稿にあった表記法を使うことができます。

ngOnInit() { 
    var nav = document.getElementById("uhf-c-nav"); 
    var anchors = nav.getElementsByTagName("a"); 

    for (let anch of anchors) { 
     anch.addEventListener(
     "click", 
     (event) => { 
      event.preventDefault(); 
      console.log("this is the element the event is bound to: " + anch.id); 
      console.log("the event target is the clicked element: " + event); 
      console.log("anch: " + anch); 
      console.log("anch.pathname: " + anch.pathname); 

      this.globalNavigationHandler(anch.pathname); 
     }, 
     false 
    ); 
    } 
+0

私はこれを試してみましたが、うまくいきませんでした。 –

+0

私の答えは残りの部分がどのように見えるかで更新されました。以下で推奨するestusのような変数として 'this'を格納しない場合は、太い矢印の関数を使用してコンテキストを保持し、アンカーを別の方法で参照する必要があります(彼も同じように) – diopside

+0

ここでは、 - https://plnkr.co/edit/zaWfU4KGG708tOZnlztj – diopside

関連する問題