I have an Angular JS project using Angular UI-Router which is going great but I am trying to implement the UI Bootstrap pagination directive and can't work out the correct strategy.
I have a table of data shown 1 page at a time and I have the pagination directive in place showing the correct number of page links. When you click a link it gets the new page number and makes a Restangular call to the api to get the new records and binds them to the table.
That's all working well, but obviously when you page through the data the URL doesn't change so the user can't use the browser back/forward buttons to navigate their history. Ideally I would like to use the following URLs:
/contacts
/contacts/page-2
/contacts/page-3
I would also like to include sorting in the URL but that's another question.
I could achieve this but by manually transitioning to a new state when one of the pagination buttons is clicked, but that would reload the controller and all of it's contents, making additional ajax calls to the server and making ugly flashes of un-styled content as it recreated the pagination control etc.
Ideally I would be able to change the URL and add a history state but without triggering an actual state change and reloading/running the controller for that view. I'm not sure if this is even possible, let alone how to do it.
Anybody got any ideas?
This is easily achievable with $stateParams
For example
$stateProvider
.state('contacts',{
url: '/contacts',
templateUrl: 'contacts.html'
}).state('contacts.paginated', {
url: "/contacts/page-:pageNum",
templateUrl: 'contacts.html',
controller: function ($stateParams) {
// If we got here from a url of /contacts/page-2
expect($stateParams).toBe({pageNum: 2});
}
})
I would choose a different pagination scheme however
Either /contacts/page/1 or /contacts?page=1
both are easily achievable with ui-router
Related
I'm relatively new to Vue, and I'm working on a portfolio site that is essentially structured like a blog with single/detail views for each project, i.e. SingleProject.vue and are linked using dynamic routes based on the slug name, i.e. path: "/projects/:project_name_slug". In the template, I'm using Axios to request JSON data from a CMS, and passing the data to a post variable via a fetchPosts() function. I'm then running this.fetchPosts() on the mounted life cycle hook. On this single project view, I also have links to the next and previous projects based on the order defined in the CMS. I'm saving JSON data to respective arrays for nextPost and prevPost and then creating router links using the post slug names as follows:
<router-link
v-if="nextPost"
:to="{path: '/projects/' + nextPost.project_name_slug}"
>Next Project</router-link>
Now to get to my actual question: these links for next/previous posts work fine; but when clicked, the view does not fully refresh/transition, and all the text data—title, sidebar info, etc.— changes rapidly, but the images lag a bit while they're downloaded (see diagram below for a visual.) So, for a moment, one will see an image from the previous project alongside text info for the next one, while the new image loads. This is a bit distracting/off-putting, so I'm trying to find a way to essentially reload the view (as if one were clicking to a different [static] route altogether) when clicking on one of these links to change the dynamic route. I found this helpful SO post, which suggests adding a changing key to <router-view> to trigger a full lifecycle whenever the path changes, i.e.
<router-view :key="$route.fullPath"></router-view>
This approach works, and indeed forces the whole SingleProject view (images and all) to refresh when changing routes via the next/previous links. However, I'm wondering if there is a better/more efficient way to limit this lifecycle refresh to just the dynamic (project view) routes? I realize, as noted in that thread, this approach could impact performance by forcing the recycle on all route changes, not just those related to single project views. Please let me know if this is unclear in any way- and thanks for any insight!
If you want to earn such kind of thing you can do it by putting all needed routes into a variable which is an Object. Then you can define some logics to switch between them and apply to a component and use it globally.
Ah, by the way, You can use a good tool called Vuepress. It has its own Previous and Next link buttons. You can say it is for documentation. No you can make blogs and portfolios too. There are so many projects created with Vuepress on the internet.
And even you can change layouts, styles or create your own theme from zero.
Below you can find link to many different projects and websites.
And most of them are ready themes to use in your projects.
https://github.com/topics/vuepress-theme
In my application, I have a multi-page form that lives on the URL http://localhost:3000/form. When I change pages in the form, the URL remains the same, but the state changes to render different views (pages of the form).
A new feature I want to implement is to allow the browser back button to switch views/pages (aka change state) in the multi-page form.
Is this possible? How can I achieve this?
Why exactly do you want to keep the same route? If a user wants to get back to the same state they were at via a deep link they would not be able to with this implementation would they?
If you want to use the same route you can at least use # routes to keep track of where in the form the user is.
Eg.
http://localhost:3000/form#step1,
http://localhost:3000/form#step2
then the back button would work to move them back a step.
my angular application consist of some common custom filters with different report pages.
User Can navigate from one page to another page and he can change filter for each page.
Need to add feature so common filters would maintain for each page.Whenuser navigated back to previous page it should display same filters that user selected in previous page.
For Above use case is it right to use ng-redux else how i can achieve this in angular 4
Please suggest best approach.
I assume by navigating from one page to another, you are basically routing to different routes. Therefore to have the information of your selected filter for each page, you can add that information to the routing parameter.
Something like this:
this.router.navigate(['/your_route_name',{parameterName: parameterValue}]);
And on the routed component, it can be received as such:
this.route.snapshot.paramMap.get('parameterName')
Or else you can have a service running globally between your routes, which is not recommended as it populates the global space unnecessarily.
I'm having some troubles understanding Angular $location, and the difference and the HTML5 mode and the default one. (yes, I've already the guide about it).
Let's say I want to build a TODO list app.
I'd like to have one page 'myapp.com/user/#1' to display the user information. 'myapp.com/user' will perform a standard GET request and load the page while Angular will intercept the hash part and say 'perform an AJAX request to get the information about user 1'. So if I just change '#/1' to '#/2' I won't get a full reload of the page.
I'd also like a 'myapp.com/todo/#1' page with the same behaviour with the todo lists. If I come from the user page to this one I get a full reload (because they're completely different pages).
How should I configure the $location service to get this working ?
I've tried setting the HTML5 mode to true, but when I click a link, I never get a full reload, and the hash character is not in the URL.
I also tried setting HTML5 mode to false, and hashPrefix('') so I get the full reload when I change pages, but $location.hash() returns an empty string and $location.path() returns '/1'.
Bonus question: what if I also want to put the ID of an item of the todo list, something like 'myapp.com/todo/#1/#2' ? (having different hash parts or something) ?
I know we can reload the current page in angularjs using $window.location.reload();.
How can we reload to a different location, something like -
$window.location.reload('/anotherUrl');
If you want to use AngularJS to change the view from code and add the change to history do this:
$location.url('/anotherUrl');
(if you want to lose current page's search (query params) and hash),
or
$location.path('/anotherurl');
(if you want to pass current url's search (query params) and hash to the new page)
If you don't want to add this change to history do this:
$location.replace();
$location.url('/anotherUrl');
or
$location.replace();
$location.path('/anotherurl');
$location.replace(); will maintain your state without re-instantiating your scope or controller. If you truly do want to reload the page (and thereby lose your state) you could fall back to the pure JavaScript solution given in the comment made by #null, that you have requested be given as an answer, or use the method I outline above and then call:
$route.reload();
Please see this link for replace(); documentation.
I have assumed you are using routing since your question is asking how to do this using AngularJS.
You are trying to redirect to different location, for that you can use window services like this
$window.location.href = 'anotherUrl' ;
I think what your looking for is to use $location service.
Specifically, you can set a new url with this:
$location.path('/anotherUrl');