【问题标题】:Return specific object from a JSON object array从 JSON 对象数组返回特定​​对象
【发布时间】:2015-07-09 21:08:31
【问题描述】:

这是我的 services.js 的样子:

    var app = angular.module('starter.services', [])


    .factory('Studies',function($http,$filter){
        var studies = [];
        $http.get("studies.json").success(
                function(data){
                    //studies = data;
                    angular.copy(data, studies);
                }
            );
        single_object = $filter('filter')(studies, function (d) {return d.nodeRef === "56e3382b-9a76-48ee-9c14-907e71b7a184";})[0];
        console.log(single_object);
      return {
        all: function(){
          return studies;
        }
    };
    })

如您所见,我对包含属性“nodeRef”的对象的 json 文件进行了获取请求,该文件恰好是一个属性。我想根据匹配的 noderef 过滤掉一个特定的对象。目前,console.log 返回“未定义”,我认为这可能是因为它在 json 文件加载之前就被调用了。如果有人可以提供解决方案,我将不胜感激。

【问题讨论】:

  • 把你的过滤逻辑放在get回调里面。
  • 我该怎么做?好吧,我确实想获取整个 json 文件,因为我还需要它来进行其他操作,然后我想执行过滤器。

标签: javascript json angularjs angularjs-scope angular-filters


【解决方案1】:

您正在执行异步请求并在服务器响应之前触发过滤器,这就是您收到 undefined 的原因,因为此时您正在将过滤器应用于空数组。

您应该将您的过滤器调用移动到 success 块内,以使其按您的意愿工作:

var app = angular.module('starter.services', [])

.factory('Studies',function($http,$filter){
    var studies = [];
    $http.get("studies.json").success(
            function(data){
                //studies = data;
                angular.copy(data, studies);
                single_object = filter("56e3382b-9a76-48ee-9c14-907e71b7a184");
                console.log(single_object);
            }
        );
  function filter(node) {
    if (studies.length > 0) {
      return $filter('filter')(studies, function (d) {return d.nodeRef === node;})[0];
    }
  }
  return {
    all: function(){
      return studies;
    },
    filtered: filter
};
})

【讨论】:

  • 这就是我不想在回调期间只执行一次过滤器的事情。如果我想从我的控制器对 JSON 数组多次运行过滤器函数怎么办?这就是为什么我正在考虑编写另一个返回函数,例如所有调用 get: function(noderef) 控制器可以调用它以通过 noderef 匹配返回特定对象
  • 查看我实现承诺的答案。您可以使用控制器中的 .then() 函数运行过滤器
  • @user1585869,检查我更新的答案。现在它创建了一个可以从外部调用的函数。您只需要确保元素已加载,否则将返回 false。但也许你可以假设他们会在从外部调用函数时准备好。
  • 所以如果我想从我的控制器调用一个特定的节点对象到这个服务,比如 $scope.x = Studies.get("noderef_string") 我该怎么做?
  • .filtered("noderef_string") 而不是 .get("noderef_string")。
【解决方案2】:

您是对的,控制台显示“未定义”,因为在 ajax 请求之后尚未填充研究。将过滤器和控制台日志移动到 .success 函数中:

$http.get("studies.json").success(
            function(data){
                //studies = data;
                angular.copy(data, studies);
                single_object = $filter('filter')(studies, function (d)  {return d.nodeRef === "56e3382b-9a76-48ee-9c14-907e71b7a184";})[0];
                console.log(single_object);
            }
        );

另外,我认为您需要在这里承诺在研究完成后更新研究。查看Angular $q

您将返回承诺,然后在 $http.success 函数中解决它,如下所示: var deferred = $q.defer(); .factory('Studies',function($http,$q,$filter){

    var studies = [];
    $http.get("studies.json").success(
            function(data){
                //studies = data;
                angular.copy(data, studies);
                //At this point you can filter data as required, or not at all. I would suggest returning the entire JSON response and not filtering here at all, let the controllers filter the data as needed to maintain a layer of separation between controller and service.

                deferred.resolve(studies);
            }
        );

  return {
    all: function(){
      return deferred.promise;
    }
};
//In your controller, or wherever else...
Studies.all().then(function(studies){ //this will fire when everything is all done. The studies variable is a full JSON object returned from the server (See deferred.resolve() in the service class). Filter here accordingly:
$scope.studies = $filter('filter')(studies, function (d) {return d.nodeRef === "56e3382b-9a76-48ee-9c14-907e71b7a184";})[0];
})

【讨论】:

  • 从我的控制器我可以做这样的事情:'$scope.studies = Studies.all(); $scope.x = Studies.get("56e3382b-9a76-48ee-9c14-907e71b7a184");'我将在运行过滤器的服务的 return 下定义一个 get 函数。这行得通吗?
  • 你仍然可以使用 Promise 模式: Studies.all().then(function(response){ $scope.studies=response; //还有你想对 $scope 做的任何事情。在这里学习});
  • Studies.all().then(function(studies){ //这会在一切都完成后触发 }) 如果我想返回我的整个研究 json 数组,我该怎么做?
  • 我已经更新了我的答案以显示返回完整的 JSON 响应,然后在控制器中过滤,使用 cmets
  • 好吧,如果我想访问整个 json 数据怎么办。会像 Studies.all().then(function(payload){ $scope.studies = payload.data; });工作吗?
猜你喜欢
  • 2022-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多