4

如何在应用程序的整个生命周期中使用保存 URL 参数状态pushState

  1. 页面加载。
  2. 转到"/search"通过href
  3. submitSearch()通过过滤器字段$location.search(fields)
  4. 转到"/anotherPage"通过href
  5. 返回"/search"通过href
  6. 搜索参数设置回上次的值。

这是某个地方的内置功能吗?

如果不是,最好的方法是什么?

4

3 回答 3

4

如果您计划通过 pushState 建立一个主要是单页的网站,您可能希望深入了解 $routeProvider ( http://docs.angularjs.org/api/ngRoute.%24routeProvider )。

为了进一步深入兔子洞,我建议查看 ui-router 模块:(https://github.com/angular-ui/ui-router)。$stateProvider(来自 ui-router)和 $routeProvider 的工作方式非常相似,因此有时 ui-router 文档可以提供您在 $routeProvider 的糟糕文档中找不到的见解。

我建议逐页阅读五页的 ui-router 文档 ( https://github.com/angular-ui/ui-router/wiki )。

在所有这些序言之后,这是实用的:您将设置一个保存历史数据的工厂,并使用 $routeProvider/$stateProvider 中定义的控制器来访问和操作该数据。

注意:工厂是服务。服务并不总是工厂。命名空间去:

angular.module.<servicetype[factory|provider|service]>. 

这篇文章解释了服务类型:https ://stackoverflow.com/a/15666049/2297328 。重要的是要记住它们都是单例。

前任:

var myApp = angular.module("myApp",[]);
myApp.factory("Name", function(){
  return factoryObject
});

代码看起来像:

// Warning: pseudo-code
// Defining states
$stateProvider
  .state("root", {
    url: "/",
    // Any service can be injected into this controller.
    // You can also define the controller separately and use
    // "controller: "<NameOfController>" to reference it.
    controller: function(History){
      // History.header factory
      History.pages.push(History.currentPage);
      History.currentPage = "/";
    }
  })
  .state("search", {
    url: "/search",
    controller: function(History, $routeParams) {
      History.lastSearch = $routeParams
    }
  });

app.factory('<FactoryName>',function(){
  var serviceObjectSingleton = {
    pages: []
    currentPage: ""
    lastSearch: {}
  }
  return serviceObjectSingleton
})

如果您想知道 $routeProvider 和 $stateProvider 之间的区别是什么,那只是 $stateProvider 具有更多功能,主要是嵌套状态和视图...我认为。

于 2013-07-19T16:55:52.847 回答
2

最简单的方法是使用cookies,angularjs为此提供了包装服务。只需在您转到“/search”时使用“$cookieStore.put()”保存您当前的 URL 参数,一旦您返回,您就可以使用“$cookieStore.get()”获得所需的内容。

请参阅angularjs cookie 商店的文档

于 2013-07-19T15:30:27.653 回答
1

我做了一个locationState服务,你只需给它你想要保留的值,它就会将它们存储在 URL 中。因此,您可以在应用程序的所有路由中存储所需的所有状态。

像这样使用它:

angular.module('yourapp')
.controller('YourCtrl', function ($scope, locationState) {
  var size = locationState.get('size');
  ;
  // ... init your scope here
  if (size) {
      $scope.size = size;
  }
  // ...and watch for changes
  $scope.$watch('size', locationState.setter('size'));
}

这是代码:

// Store state in the url search string, JSON encoded per var
// This usurps the search string so don't use it for anything else
// Simple get()/set() semantics
// Also provides a setter that you can feed to $watch
angular.module('yourapp')
.service('locationState', function ($location, $rootScope) {
    var searchVars = $location.search()
    , state = {}
    , key
    , value
    , dateVal
    ;

    // Parse search string
    for (var k in searchVars) {
        key = decodeURIComponent(k);
        try {
            value = JSON.parse(decodeURIComponent(searchVars[k]));
        } catch (e) {
            // ignore this key+value
            continue;
        }
        // If it smells like a date, parse it
        if (/[0-9T:.-]{23}Z/.test(value)) {
            dateVal = new Date(value);
            // Annoying way to test for valid date
            if (!isNaN(dateVal.getTime())) {
                value = dateVal;
            }
        }
        state[key] = value;
    }

    $rootScope.$on('$routeChangeSuccess', function() {
        $location.search(searchVars);
    });

    this.get = function (key) {
        return state[key];
    };
    this.set = function (key, value) {
        state[key] = value;
        searchVars[encodeURIComponent(key)] = JSON.stringify(value);
        // TODO verify that all the URI encoding etc works. Is there a mock $location?
        $location.search(searchVars);
    };
    this.setter = function (key) {
        var _this = this;
        return function (value) {
            _this.set(key, value);
        };
    };
});
于 2013-12-09T11:18:24.277 回答