列出页面和详细信息页面的数据,没有2个API调用

时间:2016-06-15 11:21:29

标签: javascript angularjs

我已经设置了一个服务来从我的API返回客户列表。使用UI路由器,我可以成功地将客户端的ID传递给详细信息状态 - 但是,当我在控制器中拥有所有必需的数据时,此处似乎没有必要再次调用API来检索单个客户端。 p>

在详细状态URL中使用ID显示该客户端数据的最佳方法是什么?此外 - 如果用户直接浏览客户端详细信息URL,我需要调用API来获取客户端数据 - 或者是否有更好的方法?

编辑:我不打算在同一页面上加载这两个视图,但是完全切换视图,从列表页面到详细信息页面。

App.js

中的路线
$stateProvider
    .state('root', {
        abstract: true,
        url: '',
        views: {
            '@': {
                templateUrl: '../partials/icp_index.html',
                controller: 'AppController as AppCtrl'
            },
            'left-nav@root': {
                templateUrl: '../partials/left-nav.html'
            },
            'right-nav@root': {
                templateUrl: '../partials/right-nav.html'
            },
            'top-toolbar@root': {
                templateUrl: '../partials/toolbar.html'
            }
            /*'footer': {
                templateUrl: '../partials/agency-dashboard.html',
                controller: 'AppController as AppCtrl'
            }*/
        }
    })
    .state('root.clients', {
        url: '/clients',
        views: {
            'content@root': {
                templateUrl: '../partials/clients-index.html',
                controller: 'ClientsController as ClientsCtrl'
            }
        }
    })
    .state('root.clients.detail', {
        url: '/:clientId',
        views: {
            'content@root': {
                templateUrl: '../partials/client-dashboard.html',
                //controller: 'ClientsController as ClientsCtrl'
            }
        }
    })
    // ...other routes

服务,也在 app.js

.service('ClientsService', function($http, $q) {
    this.index = function() {
        var deferred = $q.defer();
        $http.get('http://api.icp.sic.com/clients')
            .then(function successCallback(response) {
                console.log(response.data);
                deferred.resolve(response.data);

        },
        function errorCallback(response) {
           // will handle error here 
        });
        return deferred.promise;
    }
})

我的控制器代码在 ClientsController.js

.controller('ClientsController', function(ClientsService) {
    var vm = this;
    ClientsService.index().then(function(clients) {
        vm.clients = clients.data;
    });
});

最后,我的商家信息页 clients-index.html

<md-list-item ng-repeat="client in ClientsCtrl.clients" ui-sref="clients-detail({clientId : client.id })">
    <div class="list-item-with-md-menu" layout-gt-xs="row">
        <div flex="100" flex-gt-xs="66">
            <p ng-bind="client.name"></p>
        </div>
        <div hide-xs flex="100" flex-gt-xs="33">
            <p ng-bind="client.account_manager"></p>
        </div>
    </div>
</md-list-item>

2 个答案:

答案 0 :(得分:3)

我会更改服务以缓存数据。使用$q.when(),您可以从变量返回承诺。因此,您将响应保存在变量中,在执行API调用之前,请检查是否已设置缓存。如果有任何缓存,则返回数据本身。否则,你会做通常的承诺电话。

.service('ClientsService', function($http, $q) {
    var clients = null;

    this.getClient = function(id) {
        if (clients !== null) {
            return $q.when(id ? clients[id] : clients);
        }

        var deferred = $q.defer();
        $http.get('http://api.icp.sic.com/clients').then(function(response) {
            clients = response.data;
            deferred.resolve(id ? clients[id] : clients);
        }, function (response) {
            // will handle error here
        });

        return deferred.promise;
    }
})

答案 1 :(得分:3)

您可以使用建议的here等继承状态。

$stateProvider
    // States
 .state("main", {
      controller:'mainController',
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.details", {
      controller:'detailController',
      parent: 'main',
      url:"/:id",
      templateUrl: 'form_details.html'
  })  

您的服务不会改变。 您的控制器检查模型是否已被检索:

app.controller('mainController', function ($scope, ClientsService) {
  var promise = $scope.Model ? $q.when($scope.Model) : ClientsService.index();
  promise.then(function(data){
    $scope.Model = data;
  });
})
app.controller('detailController', function ($q, $scope, ClientsService, $stateParams) {
  var promise = $scope.Model ? $q.when($scope.Model) : ClientsService.index();
  promise.then(function(data){
    $scope.Model = data;
    $scope.Item = data[$stateParams.id];
  });
})

请参阅 http://plnkr.co/edit/I4YMopuTat3ggiqCoWbN?p=preview

[UPDATE] 如果必须,您也可以combine both controllers

app.controller('mainController', function ($q, $scope, ClientsService, $stateParams) {
  var promise = $scope.Model ? $q.when($scope.Model) : ClientsService.index();
  promise.then(function(data){
    $scope.Model = data;
    $scope.Item = data[$stateParams.id];
  });
})