Как передать значение для обратного вызова с помощью метода 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
});