I'm using angular with UI-router and whenever I switch to a different view and then return back to the original, the controller is re instantiated.
I know that I can save the state via a service and to repopulate it afterwards, but is there some sort of option in ui-router that allows me to not reinitialize the controller?
If you have one controller for multiple views then you can uses the nested state feature of ui-router to keep track of states. See the documentation here
Related
I have an Ionic 1.3 mobile application in which I am using Angular 1.5. Each page is comprised of one or more Angular components and each one of these components may in turn contain other components, thus creating a component tree within the page.
The problem I have is that some of these components might require data from the server, which are loaded in the component's $onInit function. Since this data is retrieved asynchronously (and there might be delays) the result is for the components to appear one after the other in the page (depending on when each one manages to initialise) which doesn't make for a very "native" mobile experience. What I would like to do is find a way to know when all components have finished loading so that I can display the page only after it is really ready (all components are fully rendered).
My original idea was to "register" each component with a service when its controller initialises and then notify the service that the component is ready once the data is loaded. The service can then be responsible for showing the page when all components are ready. My problem with doing this is that components seem to initialise sequentially (ie. component1's controller initialises and then $onInit executes, then component2's controller initialises and $onInit executes, etc.) which means that my service can't really know how many components it is waiting for. Not only that, but also a component's children controllers initialise and their $onInit methods execute after the parent component has finished initialising, which means that the component also can't keep track of whether its children have initialised or not.
An alternative would be to hard-code the number of components somewhere in the page and pass it to the service through the page controller so that it knows how many components to wait for without the components needing to register themselves, but ideally I would like something a bit more maintainable (ie. something that doesn't require me to keep track of components and keep this number up to date myself).
Can anyone think of any other way I can keep track of when my page is ready using either Angular or Ionic? Ideally it would be something that can also be ported to Angular2 / Ionic2 since I expect the app to get upgraded at some point, but any suggestion is welcome.
You can try to use resolve in ui.router or ngRoute:
angular.module('app', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('mainstate', {
url: 'your-url'
,templateUrl: 'yout_template.html'
,controller: 'YourController'
,resolve: {
yourFirstData: ['serviceDeps', function(serviceDeps){
return serviceDeps.getFirstData();
}]
,yourSecondData: ['serviceDeps', 'yourFistData', function(serviceDeps, yourSecondData){
return serviceDeps.getSecondData(yourFirstData);
}
}
}
}]);
The resolve will get the data and resolve promises before loading controller.
This is an ideia.
I'm trying to create a settings page, which updates some data on the server, and upon success, updates the scope model.
The problem is that with each navigation the controller function executes, thus overriding the changes with some init values.
Is there a way to avoid this re-loading with each navigation?
alternativaley, is there a technique to retain state of data within Angular's tool set?
It's a feature of controllers. What you're looking for is an Angular service.
You should use controllers to manage (ephemeral) UI state; for retaining "business logic" state on the client, services are more suitable.
I have an angualr app with 2 views, the map view (state: app.map) and list view (state: app.list). After the data is loaded, I want to allow the user freely switch between the 2 views without reloading the page (like controller) and the data. Is that possible with ui-router? Thanks
my map is created inside the controller, so every time the controller is re-instantiated, the map is also re created, which is slow. Is it possible to avoid it?
Of course, have a look at their sample app :)
I am I new to Angular and UI Router.
Plunk http://plnkr.co/edit/1wfyrGryfGG5RtXozPFY?p=preview
Setup I have three top level application nav buttons Home, Projects, Help. They load different views home.html, projects.html and help.html using the Angular UI Router ui-view directive. This works good.
The Projects.html view has a tab bar with each tab corresponding to a project: D1, D2 D3 etc., I show the corresponding project tab using url router attributes.
Every time I click the Projects button it is reloading the tab bar completely. I loswe the current tab and hopefully if any nested views inside it. Basically the page contents of Project.html, invoking the controller as well.
I read through the wiki documents and couldnt figure out how to implement my required functionality. I am sure I am missing something. Will it always reload the view?
Question: How to avoid reloading the projects view contents so that I can retain the selected tab and all the contents as-is before switching to Home. Because I would have a lot of nested views and models on each project.
I wanted similar functionality too, but ui-router doesn't yet support it. I forked ui-router to support "parallel states" and submitted it to the project for comment. The gist of the conversation is that ui-router will eventually support some form of parallel states but not yet. In the meantime, you can try my fork of 0.2.10 which provides the parallel states that you want.
Read the conversation here: https://github.com/angular-ui/ui-router/issues/894
View the sample parallel tabs plunk here: http://plnkr.co/edit/YhQyPV?p=preview
Here is the fork; build it with grunt: https://github.com/christopherthielen/ui-router
One option would be to implement a service that can be used to maintain the previous state. Services persist over controller changes, thus they can be used to maintain the previous page state and updated when the route changes. something similar to this would work.
app.factory('persitDataService', [function(currentStateData){
var stateService = {
state:{
//your object data set to passed in data
}
//other functions here
};
return stateService
});
then in the controllers just inject the service and assign to a scope value. When the route changes just reset the data in service to new state and inject into new controller
This should work for the previous page state. If you are wanting to save the states of all previous pages then this becomes a larger problem but should be accomplished in much the same way only with a more complicated service setup.
This could also be combined with local and session storage
I'm an Angular newbie working on a Phonegap application with a few views: a map, a list, and search.
As the user interacts, each view accumulates some UI state: the map is dragged, the list gets a scroll position, a detail view is opened for a list item, a search is performed, etc. I'd like for the user to be able to navigate among views without losing this state.
When I put my views in partials in ng-view, and my nav links use href="#/path", or ng-click to trigger location.path(path), the controller is run and state is obliterated. Makes sense.
One option would be to ng-include all partials in index.html and ng-show based on the user's nav actions. However, I've found that this kind of complexity in the DOM will lead to poor Phonegap performance. It also feels that by eschewing routing, I'm losing one of the main benefits of using Angular.
Another thought: nav clicks cause traversal of browser history. Seems tricky to maintain the state of all views in parallel, however.
My question: is there a good pattern for this?
FWIW currently using Phonegap 3.0 and Angular 1.1.5. Thanks for your time.
If you want to preserve the state of the DOM in parallel views, there's an extension to ui-router called ui-router-extras. It has a a nice demo with state transitions and full DOM preservation when switching among tabs.
you can keep all the data that needs to persist between controller reloads in services
a simple example here
Preserve state with Angular UI-Router
a more complex example here that includes restoring state if the user leaves the page and then presses the back button
Maintain model of scope when changing between views in AngularJS