Как передать значение для обратного вызова с помощью метода AngularJS $http

В моем приложении AngularJS я делаю следующее

$http.get('/plugin/' + key + '/js').success(function (data) {
    if (data.length > 0) {
        console.log(data);
        // Here I would also need the value of 'key'
    }
});

Теперь мне нужно получить доступ к значению key в обратном вызове успеха, то есть мне нужно знать, какое значение оно имело, когда был запрошен запрос get().

Любая "лучшая практика", как это сделать?

PS: Я могу сделать следующее, но есть ли лучший способ?

var key = config.url.split('/')[2];

Ответы

Ответ 1

Решение 1:

$scope.key = key;
$http.get('/plugin/' + key + '/js').success(function (data) {
    if (data.length > 0) {
        console.log(data, $scope.key);
    }
});

Решение 2 (Обновлено за каждое наблюдение Джима Хонга в его ответе):

$http.get('/plugin/' + key + '/js').success((function(key) {
    return function(data) {
        console.log(key, data);
    }
})(key));

Ответ 2

Ссылка на @geniuscarrier Рабочее решение на моей стороне

$http.get('/plugin/' + key + '/js').success((function(key) {
    return function(data) {
        console.log(key, data);
    }
})(key));

С помощью @geniuscarrier я получаю

данные undefined ошибка

.

Ответ 3

С технической точки зрения, это не проблема AngularJS, а особенность javascript

прежде всего, функции, которые вы определили внутри области , будут иметь доступ к локальной переменной и параметру своей родительской области

function parent(arg){
   var local
   function child(){
       // have access to arg and local
   }
}

Сфера действительно хорошо работает с аналогией родителя-ребенка: если вы являетесь родителем, а вы владеете файлом cookie, из-за того, что вы хотите поделиться им со своими детьми... но если вы ребенок... ваш cookie ваш cookie, вашему родителю не разрешено прикасаться к нему:). Другими словами, внутренняя область видимости может обращаться к внешней области, но она не работает в обоих направлениях.

Итак, вы определенно сможете это сделать:

$http.get('/plugin/' + key + '/js').success(function (data) {
    if (data.length > 0) {
        console.log(data, key); //as long as you can pass it to $http.get as an argument
                                //you can access it here
    }
});

Во-вторых, из-за связанного с событиями характера javascript внутренняя функция сохраняет ссылки во внешние переменные функций, вы, наверное, слышали об этом

функции в javascript - это объекты

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

function ObjectA(){ // define a constructor
    var x = 10      // private variable
    changeX : function(){
                  x = 20   // access and MODIFY a variable of parent scope
              }
}

если вы можете понять, как работает private-переменная в javascript, тогда вы в основном понимаете, что такое закрытие. Таким образом, для функции обратного вызова очень возможно, что к моменту его запуска значение переменной родительской области уже изменилось. Чтобы исправить это, вы можете использовать выражение Выражение неотложной функции (IIFE)

$http.get('/plugin/' + key + '/js').success((function(currentKeyValue) {
    return function(data) {
        console.log(currentKeyValue, data);
        // again, currentKeyValue is a REFERENCE to outer function's
        // parameter. However, since String is passed by value in javascript
        // currentKeyValue of outer scope is a DIFFERENT string that has the
        // same value as KEY when it is invoked
    }
})(key)); // immediately invoke the function passing the key as a parameter

Ответ 4

Вместо того, чтобы загрязнять область или усложнять iif, еще один более чистый способ - создать функцию обратного вызова и вызвать ее с параметрами;

var myCallBack = function (key) {
  return function (data) {
    if (data.length > 0) {
      console.log(data, key);
    }
  }
}

$http.get('/plugin/' + key + '/js').success(myCallBack(key));

Ответ 5

Фу, я долго искал этот ответ, но хорошо, что он здесь. Просто обновить его, поскольку устаревшие методы обещания success и error устарели, и вместо этого мы должны использовать стандартный метод then.

Решение 2 в ответах @geniuscarrier и @jim-horng может быть переписано следующим образом:

$http.get('/plugin/' + key + '/js').then(
    (function(key) {
        return function(data) {
            console.log(key, data);
        }
    })(key),
    function(data) {
        //error handle
    });