将JSON值从一个控制器传递到另一个控制器。

时间:2021-12-07 13:53:44

I am trying to pass a JSON string value that is stored in one controller to another. I am using a custom service to pass the data, but it doesn't seem to be passing the value.

我试图将存储在一个控制器中的JSON字符串值传递给另一个控制器。我正在使用一个自定义服务来传递数据,但是它似乎并没有传递这个值。

The First controller where the JSON string value is stored:

存储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);
}

}]);

The custom Angular service - The value is received here:

自定义角服务-这里接收值:

filmApp.service('sharedService',function($log){
  vm = this;
  var value = [];
   vm.data = function(value){
      $log.info("getValue: " + value); // received value in log
          return value;
    }
});

The Second controller that wants to receive the JSON value from the First controller:

希望从第一个控制器接收JSON值的第二个控制器:

filmApp.controller('singleFilmController',['$scope', '$http','$log','sharedService',function($scope,$http,$log,sharedService){

var value = sharedService.data(value);
 $log.info("Data: " + value);

}]);

The value is received in the service but the second controller can't seem to access it. Not sure why it is happening as I'm returning the value from the data() method from the service. Also, the selectedItemChange method is used by the md-autocomplete directive.

该值在服务中接收,但第二个控制器似乎无法访问它。当我从服务返回data()方法的值时,不知道为什么会发生这种情况。同样,选择器ditemchange方法也被md-autocomplete指令使用。

3 个解决方案

#1


1  

A good approach would be using a Factory/Service. take a look at this: Share data between AngularJS controllers

一个好的方法是使用工厂/服务。看看这个:在AngularJS控制器之间共享数据

#2


1  

Technically, you can resolve this by simply changing your service definition to

从技术上讲,您可以通过简单地将服务定义更改为

(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);
}());

But it is a very poor practice to inject $http directly into your controllers. Instead, you should have a search service that performs the queries and handle the caching of results in that service.

但是直接将$http注入控制器是非常糟糕的做法。相反,您应该有一个搜索服务,该服务执行查询并处理该服务中的结果缓存。

Here is what that would like

这是它想要的

(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);
}());

It is worth noting that a fully fledged solution would likely work a little differently. Namely it would likely incorporate ui-router making use of resolves to load the details based on the selected list item or, it could equally well be a hierarchy of element directives employing databinding to share a common object (nothing wrong with leveraging two-way-binding here).

值得注意的是,一个成熟的解决方案可能会有一点不同。也就是说,它可能合并ui-router,利用解析来基于所选的列表项加载详细信息,或者,它也可能是元素指令的层次结构,使用databinding来共享一个公共对象(这里利用双路绑定没什么错)。

It is also worth noting that if I were using a transpiler, such as TypeScript or Babel, the example code above would be much more succinct and readable.

同样值得注意的是,如果我使用的是一个传输器,比如打字稿或Babel,上面的示例代码将更加简洁和可读。

#3


0  

I'm pretty new to AngularJS but I'm pretty sure all you are doing is two distinct function calls. The first controller passes in the proper value, the second one then overwrites that with either null or undefined

我对AngularJS很陌生,但我很确定你所做的只是两个不同的函数调用。第一个控制器传入适当的值,第二个控制器使用null或undefined重写该值

I usually use events that I manually fire and catch on my controllers. To fire to sibling controllers, use $rootScope.$emit()

我通常使用手动触发的事件并捕获控制器。要向同级控制器发送信号,请使用$rootScope。

In the other controller then, you would catch this event using a $rootscope.$on() call

在另一个控制器中,您将使用$rootscope.$on()调用捕获此事件

This article helped me a decent amount when I was working on this in a project.

当我在一个项目中从事这个工作时,这篇文章给了我很大的帮助。

#1


1  

A good approach would be using a Factory/Service. take a look at this: Share data between AngularJS controllers

一个好的方法是使用工厂/服务。看看这个:在AngularJS控制器之间共享数据

#2


1  

Technically, you can resolve this by simply changing your service definition to

从技术上讲,您可以通过简单地将服务定义更改为

(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);
}());

But it is a very poor practice to inject $http directly into your controllers. Instead, you should have a search service that performs the queries and handle the caching of results in that service.

但是直接将$http注入控制器是非常糟糕的做法。相反,您应该有一个搜索服务,该服务执行查询并处理该服务中的结果缓存。

Here is what that would like

这是它想要的

(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);
}());

It is worth noting that a fully fledged solution would likely work a little differently. Namely it would likely incorporate ui-router making use of resolves to load the details based on the selected list item or, it could equally well be a hierarchy of element directives employing databinding to share a common object (nothing wrong with leveraging two-way-binding here).

值得注意的是,一个成熟的解决方案可能会有一点不同。也就是说,它可能合并ui-router,利用解析来基于所选的列表项加载详细信息,或者,它也可能是元素指令的层次结构,使用databinding来共享一个公共对象(这里利用双路绑定没什么错)。

It is also worth noting that if I were using a transpiler, such as TypeScript or Babel, the example code above would be much more succinct and readable.

同样值得注意的是,如果我使用的是一个传输器,比如打字稿或Babel,上面的示例代码将更加简洁和可读。

#3


0  

I'm pretty new to AngularJS but I'm pretty sure all you are doing is two distinct function calls. The first controller passes in the proper value, the second one then overwrites that with either null or undefined

我对AngularJS很陌生,但我很确定你所做的只是两个不同的函数调用。第一个控制器传入适当的值,第二个控制器使用null或undefined重写该值

I usually use events that I manually fire and catch on my controllers. To fire to sibling controllers, use $rootScope.$emit()

我通常使用手动触发的事件并捕获控制器。要向同级控制器发送信号,请使用$rootScope。

In the other controller then, you would catch this event using a $rootscope.$on() call

在另一个控制器中,您将使用$rootscope.$on()调用捕获此事件

This article helped me a decent amount when I was working on this in a project.

当我在一个项目中从事这个工作时,这篇文章给了我很大的帮助。