Das Framework alpine.js ist sehr nützlich um interaktive Frontend-Seiten schnell und sauber hin zu bekommen. Wenn man jedoch einen AJAX Call durchführen möchte und und aus irgendwelchen Gründen kein .fetch()
nutzen kann, muss man auf das bekannte XMLHttpRequest()
Objekt zurück greifen. Innerhalb des Responses eines solchen Calls, kann man jedoch nicht mehr per this
auf die Alpine.JS Modul-Instanz zurück greifen.
Dafür gibt es aber einen Workaround um das aktuelle Alpine.js Modul global verfügbar zu machen. Der Trick ist this
im Modul Context auf ein window
Objekt zu schreiben im init()
Mini Beispiel zur Verdeutlichung:
// dummy data function alpinejs_dummy_ajax_app(){ return { 'dummy_data' : false, init() { window.this_alpinejs_module = this; // makes it globally available change_data_in_alpinejs_module(); console.log( this.dummy_data ); // --> true } } } // This could be a new XMLHttpRequest() success-handler function change_data_in_alpinejs_module(){ window.this_alpinejs_module.dummy_data = true; }
Im Beispiel mit dem Ajax call sieht es dann so aus:
function alpinejs_dummy_ajax_app(){ return { 'dummy_data' : function() { return { 'dummy_json' : 'Data 123' }; }, 'repsonse_json' : false, 'submit_data' : function() { // PREPARE AJAX POST const ajax_post_url = 'https://www.example.com/api-endpoint'; const xhttp = new XMLHttpRequest(); xhttp.open( 'POST', ajax_post_url, true ); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.onreadystatechange = function() { const is_call_success = (this.readyState == 4 && this.status == 200) ? true : false; if( is_call_success ) { const response_json = JSON.parse( this.response ); /* in current context 'this' would refer to the XMLHttpRequest Object we need to write the response data to the alpine.js object. So we be bound the current alpine.js object to a global window variable */ window.this_alpinejs_module.repsonse_json = response_json; // working version of this.repsonse_json return true; } }; // DO THE AJAX POST const data = JSON.stringify( this.dummy_data() ); xhttp.send( data ); }, init() { /* This makes the alpine.js object available out of 'this' current context. e.g. for methods in other objects */ window.this_alpinejs_module = this; // <-- I M P O R T A N T } } }