当AngularJS中的路由发生变化时,如何保留资源数据?

时间:2014-04-29 16:24:15

标签: javascript angularjs

我将基于admin app template的AngularJS连接到API。这是我的导航菜单的样子片段:

<ul>
    <li>
        <a href="#/listings"><i class="fa fa-key"></i><span data-i18n="Listings"></span></a>
        <ul>
            <li><a href="#/listings/active"><i class="fa fa-caret-right"></i><span data-i18n="Active"></span></a></li>
            <li><a href="#/listings/need-photos"><i class="fa fa-caret-right"></i><span data-i18n="Need Photos"></span></a></li>
        </ul>
    </li>
</ul>

正如你所看到的,我有一个主要的&#34;清单&#34;页面以及列表的两个子页面,它们只是主要数据集的子集。

在我的listingCtrl中,我使用了我创建的Listing资源来从API获取JSON数据。然后将该数据填充到我的$scope中。从控制器中过滤数据非常容易,但导航菜单不在listingCtrl范围内。

这是我的列表控制器的片段,用于获取资源:

angular.module('app.listings', [])
.controller('listingCtrl', [
    '$scope', '$filter', '$location', 'Listing'
    ($scope, $filter, $location, Listing) ->

    # The listing controller checks the last segment of the URL
    # to determine which API call to place
    segments = $location.url().split('/')
    parameter = segments[segments.length-1]

    Listing.get({listingId: parameter}, (listings) ->
        $scope.listings = listings
    )
])

这是此特定页面的路由提供程序的配置:

angular.module('app', [
    'ngRoute'
])
.config([
    '$routeProvider'
    ($routeProvider) ->
        $routeProvider
            .when('/listings/:status?'
                templateUrl: 'views/listings/list.html'
            )
])

我希望通过在一个/listings方法下指定所有when路由,它会阻止在这些路由之间切换时重新加载控制器。显然情况并非如此。

Listing/listings/listings/active之间切换时,我不想重新加载/listings/need-photos资源,但我确实希望更改位置哈希值。目前,当我点击其中一个导航链接时,它会更改哈希值,显然$routeProvider会重新加载templateUrl和关联的listingCtrl,这会抛出我现有的列表数据并从中重新加载服务器。我宁愿让数据保持不变,只有在三个URL之间导航时才会更改过滤器。

如何让我的控制器和路由器协同工作,以便在上述路由之间切换时不会重新加载我的REST资源?

1 个答案:

答案 0 :(得分:2)

@Nikos是正确的。您可以提供服务来为您的商家信息保留缓存:

    app.factory('cacheExample', ['$cacheFactory', function($cacheFactory){
        return $cacheFactory('listingsData');
    }]);

将服务注入您的控制器并使用它将列表分配给缓存,如果先前已缓存列表,则不要进行API调用。应该看起来像:

    app.controller('listingCtrl', ['$scope', 'Listing', 'cacheExample', ($scope, 
    Listing, cacheExample){
        var listingsCache = cacheExample.get('listingsData');
        if(listingsCache){
            $scope.listings = listingsCache;
        }
        else{
            //the cache is empty, so make your API call with the Listing service 
            //and assign the result to the cache
            // ... other methods....
            Listing.get({listingId: parameter}, function(listings){
                $scope.listings = listings;
                cacheExample.put('listingsData', listings);
            });   
        }
    }]);

或者,您可以使用上述服务,将其注入您的控制器,并将其与$ http:

的缓存选项一起使用
    app.controller('ListingCtrl', ['$scope', '$http', 'cacheExample', function($scope,
    $http, cacheExample){
        $http.get('/listingsUrl', {cache:  
        cacheExample}).success(function(response){
            $scope.listings = response;
        });
    }]);

这是a fiddle demonstrating the second case。请注意,如果您使用带有缓存选项的$ http,则数据的传递与实际请求的传递方式是异步的,即使响应是从缓存中提供的。