2017-05-13 7 views
0

私はコードをよりプラグインのタイプのコードに変換しようとしていますので、今後クラス名を変更する場合はすべてが分離されます。未定義のプロパティ 'ドロップダウン'を読み取ることができません

私のコードで何らかの理由でCannot read property 'dropdown' of undefinedと表示されます。

私の推測では、機能を設定する前にNavigation.bindEvents()が実行されているので、見つけられません...しかし、それを解決する方法はわかりません。ここ

let Navigation = { 
    config: {}, 

    init(config) { 
     this.config = config; 
     this.bindEvents(); 
    }, 
    bindEvents() { 
     $(this.config.trigger).on('click', this.toggleNavigation); 
     $(document).on('click', this.hideAllDropdowns); 
    }, 

    toggleNavigation(event) { 
     // Store the current visible state 
     var visible = $(this).siblings(this.config.trigger).hasClass('visible'); 


     // Hide all the drop downs 
     this.hideAllDropdowns(); 

     // If the stored state is visible, hide it... Vice-versa. 
     $(this).siblings(this.config.content).toggleClass('visible', !visible); 

     event.preventDefault(); 
     event.stopPropagation(); 
    }, 

    hideAllDropdowns() { 
     $(this.config.dropdown + ' ' + this.config.content).removeClass('visible');  
    } 
} 

export default Navigation; 

そして、私はすべてのinitの機能を実行するファイルは私のapp.jsです:

は、ここに私のNavigation.jsファイルです。

window.$ = window.jQuery = require('jquery'); 

import Navigation from './layout/navigation.js'; 


Navigation.init({ 
    dropdown: '.dropdown', 
    trigger: '.dropdown-trigger', 
    content: '.dropdown-content' 
}); 

答えて

2

私はあなたがスコープに問題$(document).on('click', this.hideAllDropdowns);

のは、UPDATE

bindEvents() { 
     $(this.config.trigger).on('click', this.toggleNavigation); 
     $(document).on('click', this.hideAllDropdowns.bind(this)); 
    }, 

を試してみましょうだと思います:

bindEvents() { 
     $(this.config.trigger).bind('click', {self:this}, this.toggleNavigation); 
     $(document).on('click', this.hideAllDropdowns.bind(this)); 
    }, 

そして内event.data.selfによってすべてthis.configを交換しますfunction

+0

...明らかに、その値は、あなたのメソッドが呼び出された場所に依存していることを意味し、動的である私は、それらの両方のためにそれを追加しました、これは、私がクリックしたところで、「未定義の適切なドロップダウンを読むことができない」という前の状況と比べて何もしません。 – Akar

+0

まだエラーがありますか?そうでない場合は、あなたのクリックハンターに別の問題があると思います。 $(this.config.dropdown + 'this.config.content)の代わりに$(this.config.content)を使うべきでしょう –

+0

私はそれを修正しました。これは 'this'の使用に関連する問題でした。クリックハンドラの中で 'this'はオブジェクトへの参照をしなくなりました。この場合は' Navigation'です。すべての 'this'ステートメントを' Navigation'に変更しました。私はこの答えをアップヴォーヴします。それは私にヒントを与えたからです。ありがとう。 – Akar

1

thistoggleNavigationは、クリックされた要素を指します。

これは、兄弟要素を取得するために$(this).siblings(...)を行うことができる理由です。

ナビゲーションオブジェクトへの参照が必要です。おそらく、あなたは余分なデータ$(this.config.trigger).on('click', this, this.toggleNavigation);

を渡すことができますon構文を使用することができます次に

toggleNavigation(event) { 
    //get the navigation reference 
    var nav = event.data; 
    // Store the current visible state 
    var visible = $(this).siblings(nav.config.trigger).hasClass('visible'); 


    // Hide all the drop downs 
    nav.hideAllDropdowns(); 

    // If the stored state is visible, hide it... Vice-versa. 
    $(this).siblings(nav.config.content).toggleClass('visible', !visible); 

    event.preventDefault(); 
    event.stopPropagation(); 
}, 
1

ハンドラを書き換えthisの行動はJavaScriptで理解するための最も困難なものの一つです。私は、ドロップダウンをクリックすると、ここでthis

let module = { 
 
    config() { 
 
    console.log(`config(): 'this' is 'module' ---> ${Object.is(this, module)}`); 
 
    console.log(`config(): 'this' is 'document' ---> ${Object.is(this, document)}`); 
 
    }, 
 
    init() { 
 
    console.log(`init(): 'this' is 'module' ---> ${Object.is(this, module)}`); 
 
    console.log(`init(): 'this' is 'document' ---> ${Object.is(this, document)}`); 
 
    
 
    module.config(); 
 
    } 
 
}; 
 

 
$(document).ready(module.init);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

関連する問題