Javascript объекты и асинхронные вызовы - PullRequest
0 голосов
/ 22 марта 2012

Я пытаюсь более объектно-ориентированный подход с javascript и реализовал класс с некоторыми методами с помощью class.prototype.

Но у меня есть проблема.

Я пытался использовать метод из myclass в качестве функции успеха вызова ajax.Проблема в том, что я не могу использовать this в этом методе, когда ajax вызывается обратно.IE:

MyClass.prototype.myMethod = function(data)
{
this.data = data; /* in here this is the window object */
}
var myClass = new MyClass();
$.ajax:
    success:myClass.myMethod;

Я что-то не так делаю?

Редактировать: Полная функция, чтобы попробовать

не я

method

    function MyClass()
{
    this.name="myclass";
};

MyClass.prototype.print = function()
{
    alert(this.name);
};

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:function(data){
            func(data);
        }
    });
};


var refreshGroups = function(groups)
{
    var myClass = new MyClass();
    myAjax(myClass,myClass.print);
    return;
}

Результат: предупреждение пусто

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

"Проблема в том, что я не могу использовать это, когда этот метод вызывается ajax."

Используйте свойство context:$.ajax вызов.

$.ajax({
    url:...,
    context: myClass,
    success: myClass.myMethod
});

или использование $.proxy ...

$.ajax({
    url:...,
    success: $.proxy(myClass, 'myMethod')
});

Учитывая обновленный код, вам нужноизмените func(data) на вызов из контекста вызова, который вы установили с помощью context:, так что вы делаете this.func(data) ...

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:function(data){
            this.func(data);
        }
    });
};

... но так как вы ничего не делаете в этоманонимная функция, кроме вызова переданной вами функции и передачи аргумента, вы можете просто сделать complete:func ...

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:func
    });
};

... и контекст вызова func будет установлен вобъект, который вы передали, и аргумент data все равно будет передан функции.


Конечно, это не проблема, как работает ваш код, потому что у вас уже есть закрытыйссылка на ваш контекст, так что вы можете просто пропустить прохождение func и просто получить его прямо из вашего объекта ...

var myAjax = function(context_) // <-- no function argument needed
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        complete:function(data){
            context_.print(data);
        }
    });
};

var refreshGroups = function(groups)
{
    var myClass = new MyClass();
    myAjax(myClass); // <--just pass the object
    return;
}
0 голосов
/ 22 марта 2012

Методы в JavaScript на самом деле никак не связаны со свойствами объекта; это просто ценности. Когда вы ссылаетесь на такую ​​функцию, тот факт, что this был задействован при настройке вызова ajax, полностью теряется.

Существует новый API для помощи:

success: this.myMethod.bind(this) // or myClass.myMethod.bind(myClass) ...

Этот метод .bind() (из прототипа функции в новых браузерах) возвращает другую функцию, которая будет вызывать ваш метод, гарантируя, что this правильно настроен для этого вызова.

На сайте MDN доступна polyfill версия «bind» (и есть и другие). В качестве альтернативы вы можете сделать то же самое явно:

var obj = this;
$.ajax({
  // ...
  success: function() { obj.myMethod(); },
  // ...
});

Эта переменная "obj" необходима для хранения значения внешнего контекста this.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...