admin管理员组文章数量:1326112
I am attempting to build a proof of concept single page application that uses the history api to store the state of the view such that when a user navigates using the browser's back and forward buttons, the previous state will be displayed.
This simple example is a series of page links and few values that get displayed, to show the state of the state (no pun intended).
This is all in a functional plnkr
Basic view:
<div ng-app="testApp">
<div ng-controller="testCtrl">
<h1>State Data: {{data.displayText}}</h1>
<h2>Current Page: {{data.currentPage}}</h2>
<a ng-click="goToPage(page)" ng-repeat="page in pages" class="page">{{page}}</a>
</div>
</div>
App/Controller:
var testApp = angular.module('testApp', ['ngRoute'])
.config(function($locationProvider) {
$locationProvider.html5Mode(true);
});
testApp.controller('testCtrl', ['$scope', '$location', function ($scope, $location) {
// Hardcode some pages
$scope.pages = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// Set initial data
$scope.data = {
currentPage: 1,
displayText: "This is the initial state"
};
// Set initial data in state
$location.state($scope.data);
// Watch for location changes so we can apply state accordingly
$scope.$on('$locationChangeSuccess', function (a, newUrl, oldUrl) {
$scope.data = $location.state();
});
// Move between pages
$scope.goToPage = function (page) {
$scope.data.currentPage = page;
$scope.data.displayText = "This is page " + page;
$location.search("page", page);
$location.state($scope.data);
//history.pushState($scope.data, null, '/ThisPage?page=' + page);
};
}]);
You'll notice the mented history.pushState() line. Using that line instead of the $location.search() and $location.state() lines above actually works and performs as I'd expect, but I'd like to get this working using the correct angular way.
EDIT: To be clear, I'm not asking IF I should do this the angular way. I am asking what IS the proper angular way to get this working. The two calls to $location in $scope.goToPage() do not work, but the call to history.pushState (the mented line), does work. I'm obviously missing something for how to achieve this with pure angular and that's what I need help with. Cheers!
I am attempting to build a proof of concept single page application that uses the history api to store the state of the view such that when a user navigates using the browser's back and forward buttons, the previous state will be displayed.
This simple example is a series of page links and few values that get displayed, to show the state of the state (no pun intended).
This is all in a functional plnkr
Basic view:
<div ng-app="testApp">
<div ng-controller="testCtrl">
<h1>State Data: {{data.displayText}}</h1>
<h2>Current Page: {{data.currentPage}}</h2>
<a ng-click="goToPage(page)" ng-repeat="page in pages" class="page">{{page}}</a>
</div>
</div>
App/Controller:
var testApp = angular.module('testApp', ['ngRoute'])
.config(function($locationProvider) {
$locationProvider.html5Mode(true);
});
testApp.controller('testCtrl', ['$scope', '$location', function ($scope, $location) {
// Hardcode some pages
$scope.pages = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// Set initial data
$scope.data = {
currentPage: 1,
displayText: "This is the initial state"
};
// Set initial data in state
$location.state($scope.data);
// Watch for location changes so we can apply state accordingly
$scope.$on('$locationChangeSuccess', function (a, newUrl, oldUrl) {
$scope.data = $location.state();
});
// Move between pages
$scope.goToPage = function (page) {
$scope.data.currentPage = page;
$scope.data.displayText = "This is page " + page;
$location.search("page", page);
$location.state($scope.data);
//history.pushState($scope.data, null, '/ThisPage?page=' + page);
};
}]);
You'll notice the mented history.pushState() line. Using that line instead of the $location.search() and $location.state() lines above actually works and performs as I'd expect, but I'd like to get this working using the correct angular way.
EDIT: To be clear, I'm not asking IF I should do this the angular way. I am asking what IS the proper angular way to get this working. The two calls to $location in $scope.goToPage() do not work, but the call to history.pushState (the mented line), does work. I'm obviously missing something for how to achieve this with pure angular and that's what I need help with. Cheers!
Share Improve this question edited Jan 8, 2016 at 19:35 ctorx asked Jan 8, 2016 at 0:13 ctorxctorx 6,9518 gold badges40 silver badges53 bronze badges 1- Oh you down voter, be constructive and help make this better by leaving a helpful ment. – ctorx Commented Jan 13, 2016 at 18:36
3 Answers
Reset to default 0using $location.search and state instead of history is absolutely fine according to the AngularJS documentation on their Official site.
https://docs.angularjs/api/ng/service/$location
If you are using pure AngularJS it is always remended to go through an Angular way
history.pushState is not Angular code it just a way how you can manipulate browsers history checkout the link for more details
https://developer.mozilla/en-US/docs/Web/API/History_API
So I would always prefer you to use $location.search and $location.state instead of history.pushState
This is a workaround I discovered on my own.
For whatever reason, when trying to set the $location.state() from within the goToPage() method, the state does not get set. Angular will update the url, but the state data will be null.
I found that you can use $location.search() or $location.path() to modify the url, and then subsequently utilize $location.absUrl() to make a call directly to history.pushState().
The reason this is beneficial is that you don't have to mess around with string parsing to get the URL you want. Angular takes care of that, and we just fetch the value to use with pushState().
I have to think there is a way to do this in Angular, but I haven't found it.
$scope.goToPage = function (page) {
$scope.data.currentPage = page;
$scope.data.displayText = "This is page " + page;
$location.search("page", page);
history.pushState($scope.data, null, $location.absUrl());
};
After every button press, your history state object will be set to NULL. Comment your next line in your code:
// $scope.data = $location.state();
or ment your event out, because in this case is unnecessary
/*
Watch for location changes so we can apply state accordingly
$scope.$on('$locationChangeSuccess', function (a, newUrl, oldUrl) {
$scope.data = $location.state();
});
*/
I think, after that your code will work like a charm.
本文标签: javascriptAngular locationstate() vs historypushState behaviorStack Overflow
版权声明:本文标题:javascript - Angular $location.state() vs history.pushState behavior - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742192486a2430464.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论