【问题标题】:How to work with JSON data and promises retrieved by $http.get?如何使用 $http.get 检索到的 JSON 数据和 Promise?
【发布时间】:2014-02-18 15:21:19
【问题描述】:

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

  1. 创建一个步骤列表作为指导。
  2. 通过 ng-include 显示步骤的内容。
  3. 创建指向上一步和下一步的按钮。

根据我在Service vs. Provider vs. FactoryAngularJS: factory $http.get JSON file 和类似主题中阅读的内容,我可以创建一个服务或工厂来读取 JSON。这样做会创建一个 Promise 对象,然后在数据到达时将其向下传递以填充。当将数据插入绑定到视图的模型中时,可以找到此方法。但是,如果我需要数据来计算诸如下一步按钮之类的东西,那么我所拥有的只是一个承诺对象——我还不能建立到上一步和下一步的链接并设置它们的状态。有没有办法让角度等到数据到达后再继续执行代码?这是正确的思考方式吗?

这是一个plunker 和一些代码sn-ps:

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;
     }
   }
});

控制器片段:

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>

【问题讨论】:

    标签: json angularjs asynchronous


    【解决方案1】:

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

    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
    

    这应该可以解决 Promise 的主要问题并允许您继续。你可以在这里查看和工作plunkr

    【讨论】:

    • 这行得通 - 谢谢!我不明白 .then 方法是如何工作的,现在它是有道理的。 (如果可以,我会 +1。:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 2023-02-19
    • 1970-01-01
    • 2019-04-22
    相关资源
    最近更新 更多