使用jq-plot在AngularJS视图中异步加载视图/处理promise

时间:2016-11-23 15:21:18

标签: angularjs asynchronous jqplot

我有一个jq-plot的控制器如下:

app.controller('chartCtrl', ['$scope', 'Model1', 'Model2', function($scope, Model1, Model2) {
   var model1 = new Model1();
   model1.firstAsyncMethod(function() {
      var model2 = new Model2();
      model2.secondAsyncMethod(function() {
        $scope.data = [ [1,6.5],[2,6.5],[3,7],[4,8],[5,7.5],[6,7],[7,6.8],[8,7],[9,7.2],[10,7],[11,6.8],[12,7] ];
      })
   });
}]);

正如您所看到的,我首先调用firstAsyncMethod()并将回调传递给它。此回调对secondAsyncMethod()进行另一次异步调用。只有在secondAsyncMethod()解析后,$scope.data才可用。

与此同时,我对此控制器的看法如下:

<div ng-controller="chartCtrl">
    <div ui-jq="plot" ui-options="
          [
            { data: {{data}}}
          ]
        ">
    </div>
</div>

现在,问题是当ui-options尝试在页面加载时加载data时,控制器尚未返回data。这会在angularJS中抛出解析错误。

在完全解决了第二个异步方法后,我尝试在控制器中定义图表选项,但我仍然遇到错误。我该如何解决这个问题?感谢。

2 个答案:

答案 0 :(得分:0)

您可以使用resolve,这会在加载时在控制器中提供(通常是异步提取的)数据。它在ngRouteui-router中均可用,您还必须使用$q将这些回调包含在承诺中。

将此添加到chartCtrl的路径定义中:

resolve: {
  modelData: function($q, Model1, Model2) {
    //use $q to wrap asynchronous callbacks in promises
    var deferred = $q.defer();
    var model1 = new Model1();
    model1.firstAsyncMethod(function() {
      var model2 = new Model2();
      model2.secondAsyncMethod(function() {
        var data = [ [1,6.5],[2,6.5],[3,7],[4,8],[5,7.5],[6,7],[7,6.8],[8,7],[9,7.2],[10,7],[11,6.8],[12,7] ];
        deferred.resolve(data);
      });
   });
   return deferred.promise;
  }
}

然后您可以在控制器中注入modelData

app.controller('chartCtrl', ['$scope', 'modelData', function($scope, modelData) {
  $scope.data = modelData;
}]);

答案 1 :(得分:0)

好的,所以我终于找到了一个更简单的解决方案。您需要做的就是在视图中添加ui-refresh指令:

<div ng-controller="chartCtrl">
<div ui-jq="plot" ui-refresh="data" ui-options="
      [
        { data: {{data}}}
      ]
    ">
</div>

在控制器中,您必须将data定义为异步调用之外的某个默认值,以停止抛出错误:

app.controller('chartCtrl', ['$scope', 'Model1', 'Model2', function($scope, Model1, Model2) {
    $scope.data = [[0,0]];
       var model1 = new Model1();
       model1.firstAsyncMethod(function() {
          var model2 = new Model2();
          model2.secondAsyncMethod(function() {
            $scope.data = [ [1,6.5],[2,6.5],[3,7],[4,8],[5,7.5],[6,7],[7,6.8],[8,7],[9,7.2],[10,7],[11,6.8],[12,7] ];
          })
       });
    }]);