I implemented a back button that allows the user to go back to the previous view. However, I only want this back button to affect a particular "String of Links".
Example: Say I have a side bar with three links and a main view like so,
______________________
view8 | |
view1 | MAIN VIEW |
view9 | |
______|_______________|
The view1 link pops view1 into the main view. view1 then contains a link to view2 then view2 then contains a link to view3 and so on. We will call this our "String of Links".
The view9 link pops view9 into the main view. Currently, on view9, there is a back button that will take you back to the previous page. That back button uses window.history.back(); to route to the last view.
The problem I am having is that if the user first clicks view8 then clicks view9, the back button on view9 will send the user back to view8. But I want the user to go back to the last view on the "String of Links".
How would I go about saving a view on the "String of Links" and then later calling that view and loading it into the main view?
You need to use angular's routeProvider or my personal favorite ui-router, which would allow you to enable browser history in the way that you describe.
The nasty way would be to manipulate the url using $location and ... ugh ... , I'm sorry I just gagged
Related
I have an index.html that has a top bar with links and a side bar with links. I want the center to be replaced with content (ng-view). Let's say the top bar is Pictures, Stats, Chat. The side bar is Tigers, Lions, Bears.
These never change. This is why index.html holds them. The top bar of Pictures, Stats, Chat I want to actually route to different views/controllers (replaces ng-view on index.html). Easy.
However, when inside a given view controller (let's say Pictures) I now want to know what side bar was clicked (I would like to default to a given side bar animal when Pictures is first clicked in the app since that would be required) and I'd also like to be able to copy the link directly to there (ie Pictures/Bears (but this always just goes to the Pictures controller but inside there I know Bears was clicked so I can act accordingly)).
So if I click Tigers, the controller will know this and I can code it to get pictures of Tigers.
I don't want to put that side bar into each page itself since it's always the same. I just want it on index.html to avoid repeating myself even though this would be more direct in terms of coding each top bar view. This would be something I'd fall back to in the case of what I'm asking to do isn't possible.
I'm also wondering if it's possible to maintain the current side bar value when they click on a different top link animal. So if I was in Pictures/Lions and they click Bears, it would know to route Pictures/Bears. Since it's staying in Pictures would it really even need to route? Can it route and then call a method on the Pictures controller passing in the animal so it can do what it needs to with that information?
Try making a service like animalService that keeps track of the selected animal. This will act like your own route handler for just that side menu.
The controller for the side menu would then be able to call animalService.selectAnimal(selectedAnimal) to update the selection.
Each main page controller could then watch the value of the selected animal from animalService. There are a few ways to do this, but it would probably be easiest to use a subscription based approach:
Each controller would call animalService.subscribeToChange('controllerName', callback) on initialization and then on destroy it would call animalService.unsubscribeFromChange('controllerName'). The animalService would keep a list/map of all of the subscribed controllers, so it can execute the callback every time the selectAnimal function is called and detects a change.
If you provide a code sample I could try to give a more detailed solution.
Alternatively
You could take advantage of $rootScope. I find this a bit more hacky, but it would be probably quicker to implement. The side menu can access a root scope variable via something like $root.currentAnimal, and it can both get and set that value. Then each controller can use $rootScope.$watch('currentAnimal', function() {}) to trigger something on change ($rootScope is a service).
Suppose I've 2 controllers - C1 and C2. I do a navigator.pushPage from v1.html to v2.html. And then I do a navigator.popPage on v2.html. But the popPage doesn't reload the controller C1. I'm trying to figure out a way to reload the controller, but have not been able to do that. I tried with popPage({refresh:true}) also, but that didn't help either. Here's the codepen: http://codepen.io/rohit_jain/pen/eNbyEm.
Is there any way I can achieve what I want?
Here's the real example:
On v1.html, I'm displaying the Cart details - total_cart_items or total_price. There I've a button to move to v2.html, where I display Cart contents. On v2.html, the person can reset the cart, and then go back to page v1.html. Now, I want the reset cart action to change total_cart_items and total_price on v1.html. But that's not happening.
You can achieve it using nav.resetToPage(page, options) function, which clears the page stack and add the specified page to the new stack. The options parameter corresponds to the navigator.pushPage API.
I have an ionic app that has a search template that has a form where you can query posts by keyword. I also have a service that returns the post(s) as a list on another view. All that is working well.
My search controller upon submitting the search form uses:
$state.go('app.search.results', {'searchId': hash});
so that I can have a unique url for that search. I needed this unique url to implement 'back' functionality so that if a user clicks on one of the posts in the list, after viewing the post if they decide to click back, they would get to see the results of the search still (by default they would be returned to the search form without any results anymore).
To allow for a back to search results I implemented a custom back button function and put it on the ionic back button element like this:
<ion-nav-back-button ng-click="goBack()">
and then setup a the custom function:
$scope.goBack = function() {
$window.history.back();
}
All of this works well, I can go back to search results and see them, essentially very much like normal browser back functionality.
Problem for me is that when I have gone all the way 'back' via the back button, my initial state contains the 'Back' button and clicking it does not go anywhere and the 'Back' button still shows. Ionic does pretty good about hiding the back button when it shouldn't be there but in this case not so. Any ideas for how to check when history is exhausted and hiding the back button conditionally would be appreciated.
EDIT:
Here is a jsFiddle ; Note: open fiddle in a new, separate tab to see back button issue. FYI Search is in the menu.
One of the few qualms I have with Ionic is their "smart" navigation. I have run into a lot of problems with this myself. My solution was to create a back button of my own, this back button stores previous states and their params so you can go back and not lose search results for example with your scenario.
This component gives you both a back button and breadcrumbs to use (or you can just use back button)
It is open source and feel free to use it!
jscBreadcrumbs
Strange Milk - Breadcrumbs Post
Here is your jsFiddle with the jscBreadcrumbs implemented and working:
jsFiddle
jscbreadcrumbs
You use $window.history.back(), I think you should use $ionicHistory.goBack(); instead. It can control the history and view and state in the ionic way.
I am trying to phrase this as clearly as I can.
I have a view that shows a form. I am tying an event handler to the submit button like this:
events: {
'click #bsubmit': 'save'
}
In the save function, on success, I take care to undelegateEvents() before I navigate away:
...
that.undelegateEvents();
window.router.navigate('#/home');
...
So if someone comes to this page, submits the page and goes to (actually: is sent back) the home page, is all good.
However, there is also a 'home' link shown there, which part of the top level template. It is specified like this:
Home
So if someone comes to this page, clicks on the home link, and (from there) returns to this page, the event is mapped a second time. Now when someone submits the form, it gets submitted two times.
Given that I have many views, and the navigation away can happen in many ways, what is the common pattern to undelegateEvents when navigation happens at a higher (uncontrollable) manner? Or am I doing something fundamentally wrong?
In your case you don't need to undelegate events. Simply remove your form from the DOM with $('el').remove(), javascript events will automatically be removed
The best solution would be to have a HomepageView and FormView each in the same container (let say .container).
Example of a complete scenario:
User go to #homepage, we instanciate a HomepageView and render it in .container
User go to #form, we instanciate a FormView and render it in .container
User go to #homepage, we instanciate a HomepageView and render it in .container
...etc, etc
So, each time the user navigate to a new route the previous view is replaced by the new one.
As the previous view HTML no longer belongs to the DOM you don't need anymore to undelegate events.
Of course the .container element do not belongs to our views, each view has it's own element rendered inside the .container element.
Read this blog post for more informations.
i am working on social network website where user can navigate to the album view page in many ways.
for example.
myprofile>> Gallery index page >> Album view page.
myprofile>> Gallery details page >> Album view page.
In first case back button should go to gallery index page and In second case it should go to Gallery details page.
Is there any way to add link to back button path dynamically in cakephp?
You could try using a breadcrumb-like session array. With every view you can pop a path onto the stack, and access the stack in the view (via the Session Helper) and construct the back button that way.
The stack could be as simple as a single parameter, or an array of controller, action and parameter variables to construct the path, depending on how much detail you need.
Edit: You could also use Neil Crookes' History Component: https://github.com/neilcrookes/cakephp-bits/blob/master/history_component/controllers/components/history.php
Use the breadcrump methods in the Html helper.
In your layout:
echo $this->Html->getCrumbs(' > ','Home');
In your view:
$this->Html->addCrumb('Users', '/users');
$this->Html->addCrumb('Add User', '/users/add');
In each of your views, you can add in a new crumb, or the chain of crumbs to be able to see a history of your actions.
More here: http://book.cakephp.org/view/1653/Creating-breadcrumb-trails-with-HtmlHelper