【问题标题】:Using angular.forEach with JSON将 angular.forEach 与 JSON 一起使用
【发布时间】:2015-08-07 03:52:44
【问题描述】:

我试图用我的应用程序和控制器做的是制作一个“流程图样式”的问答系统。我如何跟踪要显示的当前问题和答案是使用$scope.ActiveQuestion 和一个名为$scope.ActiveAnswers 的数组。

我无法理解 Angularjs 的 foreach 方法。我习惯于在 javascript 中使用 for 循环,并且我尝试寻找与基本 for 循环相比可以解释 foreach 的东西,但我什么也没找到。但这基本上是我试图用 foreach 做的事情。

对于当前$scope.questions[$scope.ActiveQuestions].answerIDs 中的每个answerIDs,我想进入Answers 并拉出包含该idAnswer 的数组并将其推入一个新创建的名为$scope.ActiveAnswers 的空数组中。这将让我在模板中使用 ng-repeat 并提供该问题所需的答案。

您可以在下面看到我的 Json 数据和我当前的 Controller 代码:

app.controller('QuestionsCtrl', function($scope, $http) {

    // Pull Questions data
    $http.get("includes/getQuestions.php")
    .success(function(response) {
        $scope.Questions = response;
        $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
    });
    // Pull Answers data
    $http.get("includes/getAnswers.php")
        .success(function(response) {
            $scope.Answers = response;
        });

    // Assign First Question
    if ($scope.ActiveQuestion == null) {
        $scope.ActiveQuestion = 1;
    };
    $scope.ActiveAnswers = [];
    angular.forEach($scope.Answers, function(idAnswers) {
        angular.forEach($scope.ValidAnswers, function(value) {
            if(value==idAnswers) {
                this.push(Answers)
            };
        });
    },$scope.ActiveAnswers);

});

问题:

[
    [], {
        "idQuestion": "1",
        "answerIDs": "1",
        "text": "Don't know what to watch?"
    }, {
        "idQuestion": "2",
        "answerIDs": "2,3,4",
        "text": "Okay! First question: How new to anime are you?"
    }, {
        "idQuestion": "3",
        "answerIDs": "5,6,7,8,9,10",
        "text": "So your new! Awesome I've got a ton of anime for you, But lets get more specific. What type of anime interests you?"
    }, {
        "idQuestion": "4",
        "answerIDs": "11,12,13",
        "text": "Cool, Cool. What setting would you like?"
    }
]

我已经创建了一系列答案:

[
    [], {
        "idAnswer": "1",
        "nextQuestion": "2",
        "text": "Click here to get started",
        "animeID": null,
        "checkType": "0"
    }, {
        "idAnswer": "2",
        "nextQuestion": "3",
        "text": "...I've seen some GIFs",
        "animeID": null,
        "checkType": "0"
    }, {
        "idAnswer": "5",
        "nextQuestion": "4",
        "text": "Fantasy Action Adventure",
        "animeID": null,
        "checkType": "0"
    }, {
        "idAnswer": "11",
        "nextQuestion": null,
        "text": "Steampunk (magic, guns, early 1900s)",
        "animeID": "1",
        "checkType": "1"
    }
]

奇怪的是我没有收到任何错误,但它也没有填充 ActiveAnswers 数组。任何帮助将不胜感激。

更新

应该提到的是,我最初将数据存储在 MySQL 数据库中,并使用 PHP 将其编码为 Json 来获取数据。

【问题讨论】:

  • 认为您有一个异步问题,即在您从服务器取回数据之前执行 foreach 循环。看起来您需要等待两个调用都发生,然后才能处理该 foreach。
  • 如果这是我的问题,我不确定在获取数据之前如何延迟任何命令。
  • angular 有一个 promise 提供者:$q,您可以在其中将它注入到您的控制器中,它需要一个 promise 数组,一旦解决,将执行依赖于响应的代码。
  • 查找 angular 的 $q.all,它可以与 $http.get 一起使用,因为它返回一个 promise。

标签: javascript arrays json angularjs angularjs-ng-repeat


【解决方案1】:

您可以使用 promise$q.defer() promise manager 来处理您的请求。

根据定义,$http 返回承诺。

$q.defer() 获取2个方法:

  • resolve(value) :通过给她最终值来解决我们的相关承诺

  • reject(reason) : 解决一个 promise 错误。

控制器

(function(){

function Controller($scope, Service, $q) {


  var defer = $q.defer();

  //create promise
  var promise1 = Service.get('includes/getQuestions.php"');

  var promise2 = Service.get('includes/getAnswers.php');

  //Create promise with $q
  var promiseAnswer = defer.promise;

  if ($scope.ActiveQuestion == null) {
      $scope.ActiveQuestion = 1;
  };

  //Retrieve data from promise1 & promise2
  $q.all([promise1, promise2]).then(function(response){
    //Get our question data
    $scope.Questions = response[0].data;
    //Get our answer data
    $scope.Answers = response[1].data;
    $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
    $scope.ActiveAnswers = [];

    $scope.Answers.forEach(function(elm){
      $scope.ValidAnswers.forEach(function(value){
        //Access to elm.idAnswer and not just elm
        if (value === elm.idAnswer){
          $scope.ActiveAnswers.push(value);
        }
      });
    });

    //Resolve our data
    defer.resolve($scope.ActiveAnswers);

  });

  //When all the data are processed, retrieve our data
  promiseAnswer.then(function(data){
    console.log(data);
  });

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

那么,你应该使用 Service 来处理请求:

服务

(function(){

  function Service($http){

    function get(url){
      //Return a promise with specific url
      return $http.get(url);
    }

    var factory = {
      get: get
    };

    return factory;

  }

  angular
    .module('app')
    .factory('Service', Service);

})();

当您收到多个异步请求时,最好使用 promise$q.defer()

【讨论】:

    【解决方案2】:

    我建议你做一个有问题的安排,叫,说“答案”,把它放在一个数组中,然后记录一下,比如:

    [
     ["Question"],
       ["Answer"]
       {
        "idAnswer": "1",
        "nextQuestion": "2",
        "text": "Click here to get started",
        "animeID": null,
        "checkType": "0"
       },
    ]
    

    不应该让你的循环失败

    【讨论】:

    • 这是我想做的事情,但我在我的网络服务器中使用 MySQL 服务器数据库并使用 PHP 来提取数据并将其转换为 Json,我不确定如何在 MySQL 中实现类似的功能。
    【解决方案3】:

    在您的帮助下。我想出了如何避免修改我的数据库并最终让foreach 循环工作。虽然它仍然坏了,但我在这个问题中面临的问题已经得到解决。这是我更新的代码。

    app.controller('QuestionsCtrl', function($scope, $http, $window) {
    
    // Assign first question
    if ($scope.ActiveQuestion == null) {
        $scope.ActiveQuestion = 1;
    };
    // Pull questions data
    $http.get("includes/getQuestions.php").success(function(responseQuestions) {
        $scope.Questions = responseQuestions;
        $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
    
        // Pull answers data
        $http.get("includes/getAnswers.php").success(function(responseAnswers) {
            $scope.Answers = responseAnswers;
            $scope.getActiveAnswers();
        });
    });
    
    $scope.getActiveAnswers = function() {
        $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
        $scope.ActiveAnswers = [];
        angular.forEach($scope.ValidAnswers, function(answerid) {
            angular.forEach($scope.Answers, function(answer) {
                if (answer.idAnswer == answerid) {
                    $scope.ActiveAnswers.push(answer);
                };
            });
    
        }, $scope.ActiveAnswers);
    }
    
    $scope.answerclick = function(nextQuestion) {
        $scope.ActiveQuestion = nextQuestion;
        $scope.getActiveAnswers();
    };
    
    });
    

    【讨论】:

    • 强烈建议实施 Paul Boutes $q.all 示例,而不是嵌套异步调用。
    猜你喜欢
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    相关资源
    最近更新 更多