Mootools JSON: результат вне метода / области видимости

#javascript #json #mootools

#javascript #json #mootools

Вопрос:

 var image;
var imgProperties = new Class({
    image: new Array(),
    json: function() {
        var url = protocol   "//"   host   pathname   "/myEchoFile.php";
        var jsonRequest = new Request.JSON({
            url: url,
            onSuccess: function(img) {
                this.image[0] = img.name;
                this.image[1] = img.width;
                this.image[2] = img.height;
                alert('img.name='   this.name); //alerts myImage.jpg
            }
        }).post();
        console.log("this.image[0]="   this.image[0]); //undefined
        //@fixme
        //this.image is undefined
    }
});
  

Ответ №1:

Запрос не синхронен. (следовательно, это AJAX) Для запуска, завершения и установки значений требуется время.

вы должны обратиться к экземпляру вашего класса из onSuccess и вызвать отдельную функцию, например:

 var imgProperties = new Class({

    Implements: [Events,Options],

    initialize: function(options) {
        this.setOptions(options);
    },

    json: function() {
        new Request.JSON({
            url: "//"   host   pathname   "/myEchoFile.php",
            onSuccess: this.imageLoaded.bind(this)
        }).post();
    },
    imageLoaded: function(data) {
        this.image = [data.name, data.width, data.height];
        this.fireEvent("imageLoaded", this.image);
    }
});
  

также обратите внимание на функцию .bind(this) on onSuccess , которая гарантирует, что вы указываете на экземпляр класса, а не на глобальную область видимости (объект window?), что вы делали раньше, изменяя window.image .

чтобы он работал с аноном так, как у вас было, это было бы так:

 onSuccess: function(data) {
    this.imageLoaded(data);
}.bind(this)
  

также обратите внимание, что я запускаю событие с именем imageLoaded, которое вы можете использовать из экземпляра:

 new imgProperties({
    onImageLoaded: function(imageArray) {
        // access imageArray 
        // or just access this.image instead!
        // or export it to your global namespace like before
        window.image = this.image;
        // more code that relies on window.image being defined... 
    }
}).json();
  

Комментарии:

1. Привет, большое тебе спасибо. Теперь я получил imageProperties внутри другого класса, где я мог бы установить свойства изображения для каждого изображения. Это большой шаг вперед. Есть ли решение сделать эти свойства доступными в других методах, например, в методе setImageDimensions (imageProperties)?

2. да. jsfiddle.net/dimitar/v38Ee показано, как использовать класс imgProperties в качестве микширования в другом классе. p.s. возможно, вы тоже захотите принять ответ 🙂 если вы имеете дело с несколькими изображениями, указывать this.image на последнее будет неадекватно. я бы рассмотрел этот массив.images или, что еще лучше, используйте Asset.image(s) из mootools-more и onload events для ленивой загрузки ваших данных.