【问题标题】:Javascript, AngularJS - Global variable not being correctly assignedJavascript,AngularJS - 未正确分配全局变量
【发布时间】:2014-04-24 18:14:40
【问题描述】:

范围变量 $scope.quizArray 在从控制器访问时显示为未定义。下面的代码块肯定是读取的,因为我之前已经在其中进行了测试。

 app.factory('getQuizService', function($http){
     return {
          getQuiz:function(videoId,scope){

          var $promise=$http.post("http://localhost/PHP/getQuiz.php", {'videoId': videoId});
                $promise.then(function(msg){

                          scope.quizArray = "TEST";

                        });
           }
     }
    });

控制器代码 - 服务被调用:

function getQuizList(){
       getQuizService.getQuiz(videoIdService.getId(),$scope);
       alert($scope.quizArray);
      }

但是警报产生的结果是“未定义”而不是“测试”

谁能看到我哪里出错了?任何帮助,将不胜感激。谢谢

【问题讨论】:

  • 这是使用承诺,但你没有,所以当你提醒它没有定义时,quizArray 仅在承诺解决时设置为 TEST。

标签: javascript angularjs global-variables scope single-page-application


【解决方案1】:

你这样做是有原因的吗? 看看下面的方法:

请参阅:http://docs.angularjs.org/api/ng/service/$q,了解有关承诺如何运作的更多信息。

例如,lib3d 指出的方法有效的原因:

then(successCallback, errorCallback, notifyCallback) – 无论承诺何时被解决或被拒绝,只要结果可用,就会异步调用成功或错误回调之一。使用单个参数调用回调:结果或拒绝原因。此外,在解决或拒绝承诺之前,可能会调用通知回调零次或多次以提供进度指示。

这个方法返回一个新的promise,它通过successCallback的返回值errorCallback来解决或拒绝。它还通过 notifyCallback 方法的返回值进行通知。无法通过 notifyCallback 方法解析或拒绝承诺。

代码:

app.factory('getQuizService', function($http){
 return {
      getQuiz:function(videoId,scope){

      return $http.post("http://localhost/PHP/getQuiz.php", {'videoId': videoId});

      //If you want to handle the promise here, you can include the $q service in your controller and do this:
      var deferred = $q.defer();
      $http.post("...").then(function(data) {
        //Special treatment here
        deferred.resolve(data)
      }, function(error) {
        deferred.reject(error)
      })

      return deferred.promise

      //As indicated by lib3d, you can directly do this as well:
      return $http.post("...").then(function(data) {
            //treatment
            return data
      }, function(error) {
            //error handling      
      });

 }
}).controller("Ctrl", function($scope, getQuizService) {

  getQuizService.getQuiz(1).then(function(data) {
    $scope.quizArray = data;
    //Code when everything goes ok,
  }, function(error) {
    //Code when everything goes false;
  })
})

【讨论】:

  • 第二个 promise deferred 是不必要的。不要用转换后的数据来解决它,返回转换后的数据。不要以错误拒绝它,抛出错误,或者如果没有特殊行为,则根本不实现错误处理程序。
  • 并且不要返回deferred.promise,返回返回到then的调用。但这只是改进提示:)
  • 如果您只打算在完成后返回数据,那么承诺的意义何在?我列出了两个返回作为示例,第一个让控制器直接处理 $http 返回调用,第二个承诺让您的服务进行额外的操作。如果您不使用 deferred,则必须等待 $http.post 完成才能返回任何内容,这会阻止该过程,不是吗?
  • 您的第二个返回看起来像第一个(您仍然在处理程序之外返回),除了您将与 then 调用链接,第一个参数是返回转换后数据的函数,第二个是可选的arg 抛出传入的错误。
  • 啊哈,不知道它也可以这样工作。在答案中澄清了这一点。
猜你喜欢
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 2013-04-18
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多