我正在尝试将存储在一个控制器中的JSON字符串值传递给另一个控制器。我使用自定义服务来传递数据,但它似乎没有传递值。
存储JSON字符串值的第一个控制器:
filmApp.controller('SearchController',['$scope', '$http','$log','sharedService',function($scope,$http,$log,sharedService){
$scope.results = {
values: []
};
var vm = this;
vm.querySearch = querySearch;
vm.searchTextChange = searchTextChange;
vm.selectedItemChange = selectedItemChange;
function querySearch(query) {
return $http.get('https://api.themoviedb.org/3/search/movie?include_adult=false&page=1&primary_release_year=2017', {
params: {
'query': query,
'api_key': apiKey
}
}).then(function(response) {
var data = response.data.results.filter(function(obj) {
return obj.original_title.toLowerCase().indexOf(query) != -1;
})
return data;
for (var i = 0; i < data.results.length; i++) {
$scope.results.values.push({title: data.results[i].original_title});
// $log.info($scope.results.values);
}
return $scope.results.values;
})
};
function searchTextChange(text) {
// $log.info('Search Text changed to ' + text);
}
function selectedItemChange(item) {
$scope.value = JSON.stringify(item);
return sharedService.data($scope.value);
}
}]);
自定义角色服务 - 此处收到值:
filmApp.service('sharedService',function($log){
vm = this;
var value = [];
vm.data = function(value){
$log.info("getValue: " + value); // received value in log
return value;
}
});
想要从First控制器接收JSON值的第二个控制器:
filmApp.controller('singleFilmController',['$scope', '$http','$log','sharedService',function($scope,$http,$log,sharedService){
var value = sharedService.data(value);
$log.info("Data: " + value);
}]);
该值在服务中收到,但第二个控制器似乎无法访问它。不知道为什么会发生这种情况,因为我从服务中返回 data()方法的值。此外, md-autocomplete 指令使用 selectedItemChange 方法。
答案 0 :(得分:1)
一个好的方法是使用工厂/服务。看看这个:Share data between AngularJS controllers
答案 1 :(得分:1)
从技术上讲,您只需将服务定义更改为
即可解决此问题(function () {
'use strict';
SharedService.$inject = ['$log'];
function SharedService($log) {
var service = this;
var value = [];
service.data = function (value) {
$log.info("getValue: " + value); // received value in log
service.value = value;
return service.value;
};
});
filmApp.service('SharedService', SharedService);
}());
但是将$http
直接注入控制器是一种非常糟糕的做法。相反,您应该有一个搜索服务来执行查询并处理该服务中结果的缓存。
这是想要的
(function () {
'use strict';
search.$inject = ['$q', '$http'];
function search($q, $http) {
var cachedSearches = {};
var lastSearch;
return {
getLastSearch: function() {
return lastSearch;
},
get: function (query) {
var normalizedQuery = query && query.toLowerCase();
if (cachedSearches[normalizedQuery]) {
lastSearch = cachedSearches[normalizedQuery];
return $q.when(lastSearch);
}
return $http.get('https://api.themoviedb.org/3/search/movie?' +
'include_adult=false&page=1&primary_release_year=2017', {
params: {
query: query,
api_key: apiKey
}
}).then(function (response) {
var results = response.data.results.filter(function (result) {
return result.original_title.toLowerCase().indexOf(normalizedQuery) !== -1;
}).map(function (result) {
return result.original_title;
});
cachedSearches[normalizedQuery] = results;
lastSearch = results;
return results;
}
});
}
}
filmApp.factory('search', search);
SomeController.$inject = ['$scope', 'search'];
function SomeController($scope, search) {
$scope.results = [];
$scope.selectedItemChange = function (item) {
$scope.value = JSON.stringify(item);
return search.get($scope.value).then(function (results) {
$scope.results = results;
});
}
}
filmApp.controller('SomeController', SomeController);
}());
值得注意的是,完全成熟的解决方案可能会有所不同。即它可能会使用{em> ui-router 使用resolve
来加载基于所选列表项的详细信息,或者它同样可以是使用数据绑定来共享的元素指令的层次结构一个共同的对象(在这里利用双向绑定没有错误。)
值得注意的是,如果我使用的是像TypeScript或Babel这样的转换器,上面的示例代码将更加简洁和可读。
答案 2 :(得分:0)
我对AngularJS很陌生,但我很确定你所做的只是两个不同的函数调用。第一个控制器传入适当的值,第二个控制器用null
或undefined
我通常使用手动触发并捕获控制器的事件。要触发兄弟控制器,请使用$rootScope.$emit()
然后在另一个控制器中,您将使用$rootscope.$on()
调用
This article给了我相当的帮助。