Does anyone know, how to not register a specific url in backbone history? I mean the url will be there in the router with a function associated with it, Because my app has a back button, I just don't want to register it in backbone history.
Short answer
app.navigate('posts/1/edit',{trigger:true, replace: true});
Check the original answer here
Related
IONIC has a very good feature to "cache" the state by using ion-nav-view, when user access the state in history, it will not reload the page -- Controller won't be called, and we could enable the cache globally or by page.
While working on a web site, I tend to use Angular JS directly instead of IONIC since IONIC is mainly for the mobile hybrid APP development. However, I really like the way IONIC handle the "history" and page reload. I know that we could leverage Angular Service to keep page data and achieve the similar function. But I feel it's not convenient to code and we have to put everything into service instead of controller.
Take an example here, we have a pagination search on Page A, by clicking each item to navigate to page B for the detailed item information, if we go back to Page A, we do not want to re-execute the pagination search again. I feel this is a very common requirement for most web site, IONIC's ion-nav-view could achieve this function easily without moving data to service, I wonder is there any angular JS plugins or directive which could help to achieve this function, it's something very similar as what IONIC's ion-nav-view does?
I am looking for the answer too, no lucky.
One answer is
http://www.tivix.com/blog/dont-forget-the-back-button-in-your-single-page-ap
the author mentioned ngRouter's [reloadOnSearch] option, but i doubt this answer.
From ui-router v0.2.5, there's reloadOnSearch option too, but it's not for our purpose.
another answer is
http://www.bennadel.com/blog/2801-revisiting-routing-nested-views-and-caching-with-ngroute-in-angularjs-1-x.htm
I think there's no simple way now, you have to keep controller's status, and restore controller's status on popstate event, and reproduce all controller's actions.
The other way is cache rendered-html, but how can angular touch the restored-html still?
you can use $window.history.back()
History is a consequence of navigation. So I think you are actually asking about AngularJS routing which is responsible for navigation and history management features. Angularjs has built-in router but ui-router seems to be more main stream because of its additional capabilities.
I also need the same feature and I found this lib:
http://christopherthielen.github.io/ui-router-extras/#/sticky
I think It can solve the problem but it make a problem on performance
because every opened state still working in background and use memory and cpu. (as I think)
Edit
ui-router added stiky feature please see this link:
ui-router/sticky-states
Here how you can use it
1) Add Plugin
import {StickyStatesPlugin} from "ui-router-sticky-states";
angular.module('myapp', ['ui.router']).config(function($uiRouterProvider) {
$uiRouterProvider.plugin(StickyStatesPlugin);
});
2) Mark a state as sticky
let adminModule = {
name: 'admin',
sticky: true,
views: {
admin: { component: AdminComponent }
}
}
Okay I have googled and googled and can't find anything related to my actual problem.
Basically I have a simple router defined with a few routes all of which can be rendered directly by the server if called directly.
So the backbone history is called like this.
Backbone.history.start({
'pushState': true,
'silent': true
});
I then have simple a very simple navigate
this.navigate($(event.currentTarget).attr('href'), {
'trigger': true
});
This all works correctly except for one flaw.
Lets say you start on the home page of the site which I do not have a backbone route defined for and then click a few links on the site that use the backbone router, you will get routed to the correct page and everything is fine, but then when you click the browser's back button to get back to the home page you end up seeing the contents of the first backbone route and not the actual homepage's contents.
So I am realizing that I need to store the initial page contents so that I can reinsert them into the page once I detect that I am back to the initial page that does not match a route in my Router, and then from there I need to reload in the stored version of my page.
So I would like to know if this sounds right, or if I am going down the wrong path, also does backbone offer anything to help with this scenario that I am just missing? And I can't be the only one who has tried to do this so how have others gotten around this issue?
(Initially I thought there was actually a problem with my code, and not actually this fundamental issue, so I still want to ask this question to figure out how others have accomplished this)
You need to define a route for the homepage. What happens is that each time you follow a link, the current URL is pushed on pushState's stack, and each time you hit the back button the previous URL gets popped and Backbone tries to follow its route. However, when you pop the homepage URL, there's no route that it matches so Backbone doesn't actually do anything, leaving the content as whatever it was the last time a route really did match.
Recently I found out about the undocumented $locationChangeStart event in AngularJS when trying to determine where in the framework I should be redirecting users to the login page if their session is invalid.
I'm listening for the event using the following:
$scope.$on("$locationChangeStart", function (event, nextLocation, currentLocation) {
// Logic goes here
});
where nextLocation and previousLocation are absolute urls to locations within the app.
My question is this: Does AngularJS expose the ability to be able to match a url against a route, much like its internal routing engine does to see if an absolute URL matches a defined route?
If not, what would be the best way to detect a route based on an absolute URL?
I located the relevant source code lines in the AngularJS github project. Here is the function that it uses to match the URL to a route:
Since this functionality is not exposed by Angular I decided to come up with a rudimentary way of matching the URL to a route since the routes I was matching were relatively simple compared to implementing the same route matching that Angular does.
It ain't pretty, but it works..
So we just relaunched our site as a Backbone powered single-paged app, but we're having a heck of a time tracking our conversions from our AdWords ads into the site with Google Analytics.
The problem is that in order for Google Analytics to track the fact that the user came in from AdWords, it looks for a URL query parameter called gclid in the URL:
http://test.com/?gclid=(Q#kjsdf0INKJSDJF9
But, when the Router from Backbone initializes, it removes all the query parameters from the URL, so when the tracking event fires, it doesn't see that the user came from an AdWords ad.
We tried sending the user to an interstitial page that loads the analytics code and waits for the event to fire and then forwards them into the site, but
Its ugly and shows users a blank page for a while
Doesn't work without a significant wait for IE8 users (who make up 50% of our user base sadly)
We contacted Google's AdWords help to see if we can manually give the gclid to Analytics and their answer was
You should hire one of our consultants who will figure out how to keep the URL parameters on your site so it works correctly because we do not support manually setting the gclid ID
(Sadly only a very minor paraphrase.)
Google-fu leaves me blank in this respect -- lots of people asking questions in the Google forums, but no answers.
I don't know how everything is setup, but Backbone might not be seeing that URL with the parameters as a match, or a route that it knows about. In fact, you can test that by doing something like...
unless Backbone.history.start(pushState: true)
window.location = someDefaultURL;
If you wanted just a simple way to match routes with params, here's two ways that you could do it.
class MyRouter extends Backbone.Router
routes:
'test?*params': 'test'
'testTwo?gclid=:gclid': 'testTwo'
test: (params) ->
console.log 'test route', params
testTwo: (gclid) ->
console.log 'test route two', gclid
So the issue here is that I was immediately pushing an entry into the history object with the navigate method.
This overwrites (correctly) the current URL and does not preserve URL parameters (although it would be nice if it could, I guess that's a pull request I should make).
By not calling navigate immediately this allows the URL parameter to stay in the URL long enough for G.A. to see it.
According to the Backbone.js page:
Until recently, hash fragments (#page) were used to provide these
permalinks, but with the arrival of the History API, it's now
possible to use standard URLs (/page).
I tried to add this router rule:
routes: {
'test': function() {
alert('ok'); }
}
And called the Backbone.history.start({pushState: true, root: '/myroot/'}). I have a link in my page as:
test me
I intercepted the link's click event with:
$('a[href=test]').click(function(e) {
router.navigate('test');
e.preventDefault(); });
When I click on the link, a request is not made, which I believe the interception was succeeded. But the event is not triggered.
So, please help me understand how this History API works. Or point out where I have done wrong.
You need to turn on pushState:
Backbone.history.start({pushState: true});
Your link is going to force a full refresh from your server and your server must respond with the content of that url.
You need to intercept that link's click and tell your router to navigate to the "test" route:
myRouter.navigate("test");
For more info on the HTML5 history api: http://diveintohtml5.info/history.html
for some intro level info on using pushState with Backbone:
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-1-introducing-pushstate/
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/
And a video of a presentation I gave that covers all of this:
http://lostechies.com/derickbailey/2011/10/06/seo-and-accessibility-with-html5-pushstate-part-3-the-video/
Hope that helps.
You'll need to add {trigger: true} to the navigate call to actually trigger routing events.
To indicate that you'd like to use HTML5 pushState support in your application, use Backbone.history.start({pushState: true}). If you'd like to use pushState, but have browsers that don't support it natively use full page refreshes instead, you can add {hashChange: false} to the options.
PS! If your application is not being served from the root url / of your domain, be sure to tell History where the root really is, as an option (otherwise the navigation won't work!):
Backbone.history.start({pushState: true, root: "/public/search/"})