如何使用$ http.get检索的JSON数据和promise?

时间:2014-02-18 15:21:19

标签: json angularjs asynchronous

我没有正确考虑角度的$ http.get工作,所以也许你可以帮我重新调整。我正在开发一个向导,其中每个步骤都是一个单独的html文件,步骤序列在JSON文件中。我想要做的是在JSON文件中读取然后:

  1. 创建步骤列表作为指南。
  2. 通过ng-include显示步骤的内容。
  3. 创建指向上一步和后续步骤的按钮。
  4. 根据我在Service vs. Provider vs. FactoryAngularJS: factory $http.get JSON file和类似主题中的内容,我可以创建一个服务或工厂来读取JSON。这样做会创建一个promise对象,然后在数据到达时将其传递给要填充的行。当将数据插入到绑定到视图的模型中时,这可以找到。但是,如果我需要数据来计算下一步按钮之类的东西,我所拥有的只是一个承诺对象 - 我无法建立前一步和后一步的链接并设置它们的状态。在继续执行代码之前,有没有办法在数据到达之前进行角度等待?这是考虑它的正确方法吗?

    以下是plunker和一些代码段:

    JSON:

    [{
        "name"  : "Step 1",
        "id"    : "step-1",
        "src"   : "step-1.html",
        "state" : "active"
        },
    
        {
        "name"  : "Step 2",
        "id"    : "step-2",
        "src"   : "step-2.html",
        "state" : "unavailable"
        },
    
        {
        "name"  : "Step 3",
        "id"      : "step-3",
        "src"   : "step-3.html",
        "state" : "unavailable"
    }]
    

    厂:

    workflow.factory('getWorkflow', function($http, $q) {
       return {
         getFlow: function() {
           var deferred = $q.defer();
           $http.get('steps.json').success(function(data) {
              deferred.resolve(data);
           }).error(function(){
              deferred.reject();
           });
           return deferred.promise;
         }
       }
    });
    

    Controller Snippets:

    var workflow = angular.module("workflow", ['getWorkflow']);
    
    workflow.controller("showStep", function($scope) {
        $scope.workFlow = {};         // Create the workFlow object
        $scope.workFlow.steps = [];   // Create an empty array to hold the steps
        $scope.workFlow.steps = getWorkflow.getFlow(); 
    
    ... set the first step as the active step and point to the HTML file ...
    
        $scope.workFlow.buildNavButtons = function() {
        scope.workFlow.buttonArray = [];    // Create/reset the array of buttons to nothing
    
        // The button for the PREVIOUS step.
        if ($scope.workFlow.activeStepIndex > 0) {  // Only add button if not the first step
            var prevButton = {};
            prevButton["destination"] = $scope.workFlow.activeStepIndex - 1;
            prevButton["buttonText"] = "<< " + $scope.workFlow.steps[$scope.workFlow.activeStepIndex - 1].name;
            prevButton["buttonClass"] = "workflow-previous";
    
            $scope.workFlow.buttonArray.push(prevButton);
        }
    ...
    

    HTML

    <!-- PREVIOUS AND NEXT STEP BUTTONS -->
    <div id="workflow_navigation">
        <ul>
            <li data-ng-repeat="button in workFlow.buttonArray">
                <button class = "{{ button.buttonClass }}" 
                ng-click="workFlow.updateStep(button.destination)">
                    {{ button.buttonText }}
                </button>
            </li>
        </ul>
    </div>
    

1 个答案:

答案 0 :(得分:2)

你几乎是对的,只是几个问题。 首先,您需要将工厂注入控制器,而不是作为模块的依赖项。

var workflow = angular.module("workflow", []);

workflow.controller("showStep", function($scope, getWorkflow) {

其次,在采取行动之前,你需要等待履行承诺:

  getWorkflow.getFlow().then(
    function(data) {
      $scope.workFlow.steps = data
      console.log($scope.workFlow.steps);

      // "activeStep" controls which step appears on screen.  
      // This initialize it and loads default content.
      $scope.workFlow.activeStep = $scope.workFlow.steps[0];
      $scope.workFlow.activeStepIndex = 0;
      console.log($scope.workFlow.activeStep);
      $scope.workFlow.content = $scope.workFlow.activeStep.src; // The display of the step content itself - changing this changes the display.

    }); // Use the factory below

这应该解决承诺的主要问题并允许您继续。您可以在此处查看并使用plunkr