2017-05-13 6 views
0

Ich versuche, meinen Code in eine mehr Plugin-Art von Code umzuwandeln, so dass alles getrennt wird, falls ich Klassennamen in der Zukunft ändern werde.Kann Eigenschaft 'dropdown' von undefined nicht lesen

Aus irgendeinem Grund, in meinem Code, bekomme ich Cannot read property 'dropdown' of undefined.

Meine Vermutung ist, die Funktion Navigation.bindEvents() läuft, bevor ich die Konfiguration einstellen, so kann es nicht finden ... Aber ich weiß nicht, wie man es löst.

Hier ist meine Navigation.js Datei:

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; 

Und hier ist meine app.js-Datei, die ich alle init Funktionen ausführen.

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

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


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

Antwort

2

Ich denke, du hast Probleme mit dem Umfang $(document).on('click', this.hideAllDropdowns);

Lasst uns versuchen

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

UPDATE:

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

und ersetzen alle this.config von event.data.self innerhalb toggleNavigation Funktion

+0

Ich habe es für sie beide, wenn ich das Drop-down klicken, Es macht nichts, im Vergleich zu der vorherigen Situation, wo ich geklickt habe und es sagte 'Kann nicht Property Drop-Down von undefined '. – Akar

+0

Der Fehler immer noch da? Wenn nicht, denke ich, es gibt ein anderes Problem in Ihrem Click-hanlder. Vielleicht sollten Sie $ (this.config.content) anstelle von $ (this.config.dropdown + '' + this.config.content) verwenden. –

+0

Ich habe es behoben, Es war ein Problem im Zusammenhang mit der Verwendung von 'this, When Innerhalb eines Click-Handlers bezieht sich "this" nicht mehr auf das Objekt, in diesem Fall auf "Navigation", also habe ich alle "this" -Anweisungen in "Navigation" geändert. Ich bin mir nicht sicher, ob es eine gute Sache ist, aber es hat funktioniert. Ich werde diese Antwort auffrischen, weil sie mir einen Hinweis gab. Vielen Dank. – Akar

1

this im Kontext von toggleNavigation bezieht sich auf das angeklickte Element.

Deshalb können Sie $(this).siblings(...) tun, um die Geschwisterelemente zu bekommen.

Sie benötigen einen Verweis auf das Navigationsobjekt. Vielleicht können Sie die on Syntax verwenden, die Sie zusätzliche Daten $(this.config.trigger).on('click', this, this.toggleNavigation);

Dann schreiben Sie den Handler

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

Das Verhalten von this ist eines der schwierigsten Dinge passieren lässt in JavaScript zu verstehen. Hier this ist offensichtlich dynamische, was bedeutet, dass ihr Wert hängt davon ab, wo Sie Ihre Methode aufgerufen wurde ...

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>

Verwandte Themen