How to reuse router object on another html page in Backbone JS? - javascript

I am fairly new to Backbone JS and still figuring out its nuances.
I have created a router class in main.js which is included in index.html. Also, I have created an object of that router class associated to same html page.
Now, if I redirect to next html page all the created objects get lost. Even if I associate it to window object, it also get lost on a page redirect.
So, my question is how do I reuse my router object on next html page without storing it in sessionStorage or localStorage?
Should I always include the router js file on each html page and create a new object every time? Is there any other way to achieve what I am trying to do? Please enlighten me.

Backbone.js is primarily designed to create SPAs (single Page Applications) especially the routing which is based on the hash change events by default.
For some reason if you must have actual redirection between HTML pages, then considered each as separate applications, i.e both should load the libraries, setup their own backbone components etc. Data can be shared between them using client side solutions like localStorage or REST API.

Related

Export Vue dynamic site to Static HTML on run time

I am trying to generate/export the html/css from a Vue Application to a static index.html and the css assets without the script I wrote within the vue app which makes calls to the internal servers.
Use case:
An employee creates a digital Information site about a car of the company.
Here he needs to enter vehiclenumber etc, it then makes a GraphQL query with these parameters to our internal server.
Once the information loaded and is filled in on the site, an option should be given to "Save" (Export) the html/css with only the necessary js for vue components itself to work (e.g. Element vue gallery)
The Employee creates the page using localhost:8080?carnumber=xxx&info=xxx
The Server queries itself should not be included as they will be unreachable from outside the intranet.
So I want the static html to not care about the route and parameters and display the HTML as seen on localhost:8080?carnumber=xxx&info=xxx
I have looked for "static site generators" etc but I have not come across a result I am looking for as the page itself isn't static only the export should be. I also came across Nuxt.js but not exactly how I want it to be, the best would be to have it call like a NuxtGenerateStaticPage(this) function (in my dreams)
Please let me know if anything is unclear.
I appreciate any input/idea :)

Is it possible to influence a single Angular app from multiple JS scripts?

Quick Summary:
I need to allow two script files to handle different operations for the same angular app. One needs to initialize the app, the other needs to assign a templateCache object to a piece of JSON in localStorage.
Context:
I have several python files which compile/generate html and I have constructed an angular app with this emitted html for my site (which uses CGIs).
The basic construct of the site comes pieces of HTML, which fit together like so:
|------------Header---------------|
|-Navigation-|------Content-------|
|-Navigation-|------Content-------|
|-Navigation-|------Content-------|
|------------Footer---------------|
My Header creates the <head> tag, instantiates my ng-app and uses $templateCache to set up a template that I call from my Navigation code. I had to go with templateCache instead of ngView and ngRoute due to some limitations with how the CGIs emit the html, and the order in which this happens.
My "Navigation" python/html sets up my app with JS like so:
<script>
var responsiveCatalog = angular.module('responsiveCatalog', ['ngStorage']);
....controllers...
....config, etc....
</script>
This Navigation also includes my default templateCache object:
<div ng-include=" 'responsiveItems.html' "></div>
This is all working to show my first templateCache object in the Content section. However, I need to grab many pieces of information from the python generator for the "Content" section (a totally separate file from the "Navigation"), store this data as JSON in localstorage (hence the inclusion of the ngStorage module), and call that as my second templateCache option.
I am not actually sure that I can use two separate instances of Javascript to reference and influence the same Angular app. I know this seems like bad practice, but I am trying to prevent the need to tear down a huge piece of legacy architecture to influence the angular app from two Javascript files in harmony.
Thanks in advance.
You can do
angular.module('myAppName').controllers.... in different files, just make sure the myAppName the same. Bug I don't feel like it work with config, no time to test. If you need any communication between them, check $emit and $broadcast.

Memory management in javascript

I am trying to develop an application using javascript and to help organise my code, I am coding using objects. However, I don't really understand how the javascript engine is managing my object.
If in a first HTML page1 where I include a js file, I make an object obj1 when I switch to HTML page2 where I include both the old js script (already included in the first html page ) and the second js file where I want to use that object created in the first javascript file, it's undefined.
Can anyone help me understand how javascript manages objects and how, going from page to page, to get my object ?
When you load a new page (or even reload the current one), everything that was on the page you are leaving is destroyed.
If you want to make an object persistent, consider using localStorage to save the information you need.

Caching URL view/state with parameters

I'm making a mobile app using Cordova and AngularJS. Currently I have installed ui-router for routing but I'm open to any other alternative for routing.
My desire: I want to cache certain views bound with parameters. In other words I want to cache paths (or pages).
Example situation: let's say that we see some dashboard page, click on some book cover which redirects to the path book/2. This path is being loaded for the first time into app. Router redirects from HomeController to BooksController (whatever the name). Now the BooksController loads data for given $stateParams (book id = 2) and creates view filled with info about chosen book.
What I want in this situation:
I go back to the dashboard page - it is already loaded (cached?)
I choose book #2 again
Controller or router notices that data about this book is already loaded
The view isn't being recreated, instead it's being fetched from cache
Actually, it would be best to cache everything what I visit based on path. Preloading would be cool too.
Reason: performance. When I open some list of books then I want it to show fast. When view is being created every time, then animation of page change looks awful (it's not smooth).
Any help would be appreciated.
EDIT:
First of all, since I believe it's a common problem for many mobile HTML app programmers, I'd like to precise some information:
I'm not looking for hacks but a clear solution if possible.
Data in the views uses AngularJS, so YES, there are things like ng-bind, ng-repeat and so on.
Caching is needed for both data and DOM elements. As far as I know, browser's layout operation is not as expensive as recreating whole DOM tree. And repaint is not what we can omit.
Having separate controllers is a natural thing. Since I could leave without it I cannot imagine how it would work anyway.
I've got some semi-solutions but I'm gonna be strict about my desire.
Solution 1.
Put all views into one file (I may do it using gulp builder) and use ng-show. That's the simplest solution and I don't believe that anyone knowing AngularJS would not think about it.
A nice trick (from #DmitriZaitsev) is to create a helper function to show/hide element based on current location path.
Advantages:
It's easy.
KIND OF preload feature.
Disadvantages:
all views have to be in a single file. Don't ask why it's not convenient.
Since it's all about mobile devices, sometimes I'd like to "clear" memory. The only way I can think of is to remove those children from DOM. Dirty but ok.
I cannot easily cache /book/2 and /book/3 at the same time. I would have to dynamically create DOM children on top of some templates for each view bound with parameters.
Solution 2.
Use Sticky States AND Future States from ui-router-extras which is awesome.
Advantages:
Separated views.
Very clear usage, very simple since it's just a plugin for ui-router.
Can create dynamic substates. So it would be possible to cache book1, book2 but I'm not sure about book/1 and book/2
Disadvantages:
Again, I'm not sure but I didn't found an example with caching a pair/tuple (view, parameters). Other than that it looks cool.
This is precisely the problem I had to solve for my site 33hotels.com. You can check it and play with the tabs "Filter" and "Filter List" (corresponding to different Routes), and see that the View is updated instantly without any delay!
How did I do it? The idea is surprisingly simple - get rid of the Router!
Why? Because the way the Router works is it re-compiles the View upon every single Route change. Yes, Angular does cache the Template but not the compiled View populated with data. Even if data do not change! As the result, when I used the Router in the past, the switch always felt sluggish and non-reactive. Every time I could notice annoying delay, it was a fraction of second but still noticeable.
Now the solution I used? Don't re-compile your Views! Keep them inside your DOM at all times! Then use ng-hide/ng-show to hide/show them depending on the routes:
<div ng-show="routeIs('/dashboard')">
<-- Your template for Dashboard -->
</div>
<div ng-show="routeIs('/book')">
<-- Your template for Book -->
</div>
Then create a function routeIs(string) inside your Controller to test if $location.path() matches string, or begins with string as I am using it. That way I still get my View for all pathes like /book/2. Here is the function I am using:
$scope.routeBegins = function () {
return _.some(arguments, function (string) {
return 0 === $location.path().indexOf(string);
});
};
So no need to be smart with caching - just keep it in the DOM. It will cache your Views for you!
And the best part is - whenever your data is changed, Angular will instantly update all the Views inside your DOM, even the hidden ones!
Why is this awesome? Because, as user, I don't have to wait for all the parsing and compiling at the moment I want to see the result. I want to click the tab and see my results immediately! Why should the site wait for me to click it and then begin all the re-compiling as I am waiting? Especially when this could be easily done before, during the time my computer is idle.
Is there any downside? The only real one I can think of is loading memory with more DOM elements. However, this actual byte size of my views is negligible, comparing e.g. with all JS, CSS and images.
Another possible but avoidable downside is the re-compilation cost of the hidden views. This is where you can get smart and avoid computation-heavy parts depending on the current routes.
Also, you are not re-compiling the whole View, just the parts affected by data changes, which also lowers computational cost.
I find it quite remarkable that everyone is using Routes and seems to be completely unaware (or ignorant) of this problem.
1) About static pages in the app (views), angular takes care of loading them.
for example: for your dashboard page you need not worry about caching the page, as angular will take care of it. Angular will only load the dashboard view once and on all next requests for the dashboard view, angular will just show you the view(not load the file for view), if it is all a static view without any data loaded by ajax calls.
2) if your dashboard is itself loading the book list(or similar data) via ajax, then you can tell your controller to only load the data once and store it to localstorage and on subsequent requests to the dashboard page can only load the data from the localStorage.
3) similar approach can be used when your BooksController loads the data into a view. You can check in your BooksController if the request for a particular book is been previously made and if not your can store it to localstorage or database. and if the data was previously requested then you can load the same data from the storage without making a request to server.
Example situation:
say user makes request for book1, then
your controller i.e BooksController check whether the same data was requested before,
if not, you can load the data via the ajax call from server and also save it to local storage.
if it was loaded before you will load the data stored in the localstorage or in the database.
If you're using ui.router, then you should take a look at ui.router extras, specifically the sticky states module. This allows you to cache the state 'tree' (including rendered views) so they don't have to be compiled or re-rendered on state changes.
http://christopherthielen.github.io/ui-router-extras/
Here's a demo:
http://christopherthielen.github.io/ui-router-extras/example/sticky/#/

Ember.js: How do I associate my component with a model?

I am new to Ember.js and am trying to figure out how to piece things together at this point. One component I built, since I need a re-usable "widget" to use across many portions of my application, is a "site nav" widget. Basically, it's almost like the buttons/links you see in StackOverflow when you open a new question titled: "Questions Tags Users Badges Unanswered". In my app, these links have a name and id associated with them on the server-side. I want to be able to use this navigation widget on multiple parts of my app and it should be as simple as putting:
{{site-nav}}
into a template. I got that part working just fine, but the navigation is currently hard coded in handlebars. My question is, for a component, where is the right place to retrieve/populate model data from the server? For a controller, we do it directly from the controller's route definition. The component is not associated with a router. In fact, it can be re-used, as mentioned before, in several parts of the app.
I want to be able to drop this component into templates and have it populated with modeled nav from the server which has the name/IDs of the navigation I need. Where is the best place to do this? I'm guessing I'll still extend from something like DS.Model, but I'm not entirely sure where/when/how to integrate this with the component. When do I create the model and invoke a .find() type call to the server to populate site-nav with data?
you can pass value to component Passing properties to component
via handlebars.
{{my-nav navlist=listfromserver}}
so the list from server is in our controller can be passed to the component

Categories