Maintain controller state in Angular like Durandal does? - angularjs

I like that Durandal has Activate/Deactivate methods that get called on the VM and that the views can even be cached.
Is there a way to have this same features in Angular?

You can use a service / factory. These are singletons in AngularJS and you can inject them to the controller. Strictly have one service per controller and the service will be maintained between navigations to the view / controller.
http://docs.angularjs.org/guide/dev_guide.services.creating_services
The way this would work is that your controller would take myService as an injected dependency. Then you assign it to $scope as $scope.cache = myService. Then in your view you bind to cache.someProperty for elements that wanted cached.
Just as an aside:
You can even share services containing state data between controllers. Although I would recommend against this pattern, because it looks like global state. Services you share between controllers should ideally only provide functionality instead of being data objects. Unless you are specifically looking for a global data store :)

Related

Is it bad practice to user a service to maintain state between controllers?

I have a number of sibling controllers and to the side of the screen I have some filters and options that generally can apply to any controller. My problem is that I want to preserve the state of the options for use from any of the controllers.
The way I understand this should be done from reading is to create a service which I can then inject into my controller and use the exposed getter/setter methods to access values.
However, from the AngularJS docs here the last paragraph, which advises against using $rootScope for this purpose, also notes Conversely, don't create a service whose only purpose in life is to store and return bits of data.
Is it bad practice to use a service as a singleton for passing data between controllers? What are the complications and tradeoffs and what are alternative approaches?

Best way to keep data is Factory variables or RootScope variables in angular across controllers

I have an angular application with 5000 array values in different variables. I need the same values across 3 controllers among the 5 controllers in whole project. Now I am using factory to keep the data across these. Is $rootScope a better efficient way or the current method is better.
$rootScope is a parent of all scopes so values exposed there will be visible in all templates and controllers. Using the $rootScope is very easy as you can simply inject it into any controller and change values in this scope. It might be convenient but has all the problems of global variables.
Services are singletons that you can inject to any controller and expose their values in a controller's scope. Services, being singletons are still 'global' but you've got far better control over where those are used and exposed.
See the question - Global variables in AngularJS
$rootscope is not at all a good option. It is always preferable to use factories for data sharing.

Is a new instance of service created for each controller in angularjs?

I am building an angularjs application, that has various controllers. For two of the controllers I am dependency injecting the same service. Is a separate instance of that service created for each of the controllers where it is being injected?
Short Answer
From Docs
Lazily instantiated – Angular only instantiates a service/factory when
an application component depends on it.
Singletons – Each component
dependent on a service gets a reference to the single instance
generated by the service factory.
Angular service/factory/provider are Singleton object. Which create its instance only single time and if you ask for instance again(by injecting dependency) it gives back the old instance which was already created.
You could go throw this long answer which has everything explained

What is the proper way to access a function inside a different controller

What is the proper way to access a function side controller A from inside controller B?
The best method I've been able to find is to push the functions to a shared service, so I've started to move all of my functions and logic inside this service, which feels like the wrong way to do things.
My scenario is that I have a view utilizing two different controllers. Each one has its own set of tabs for navigation. I need to be able to navigate between views and to specific tabs inside.
Is a service really the best way to do this? Or have I missed something?
The best way to communicate between two controllers is by using the service. You have common method defined inside the service and then inject that service wherever you need that function to use.
Use $broadcast service to trigger the event and all.
Following is the plnkr which shows how to communicate between the controllers.
Plnkr :http://plnkr.co/edit/d98mOuVvFMr1YtgRr9hq?p=preview

Using reusable models and injecting these where required in Angular

Anyone know the best recommended way of creating models in a separate JavaScript file and have these injected into the controllers that need them, rather than creating the models on fly normally in the controller?
This would make it so much easier to pass around the model and you would know exactly what you was passing around.
I have some thoughts on using Services, and inject these where I need i.e. controllers.
Controllers would then pass these onto specific services to do any heavy lifting to keep my controllers nice and light.
Is services the only and recommended way to go ? Or is there a better alternative way ?
Any use of third-party libraries / modules would also be considered.
I think services are the way to go. Not only are they injectable but they are also Singletons - meaning wherever they are injected, the same instance is shared.
Example of a service which uses the $http service to make an asynchronous call to retrieve data:
app.factory('customerService', function($http) {
var customers = [];
$http({ url: 'api/customers/all', method:'GET'}).success(function(data) {
angular.copy(data, customers);
});
return {
customers: customers
};
});
In your controller or directive, you can then inject the service and bind customers to your scope:
app.controller('ctrl', function($scope, customerService) {
$scope.customers = customerService.customers;
});
The best way to do it is by service for couple of reasons.
If you use ng-view and routing the service is not reloading and your data is safe in service
It's easy injectable to controllers
Provides two-way data binding between controllers
working plunker with two-way data binding between controllers
http://plnkr.co/edit/pt2xwlYqvY3r840tHJ92?p=preview
NOTE: if you don't have a dot in your model you are doing something wrong ;)
I believe services are the best way for this.
I have used scope inheritance to place some methods that most of my app would need at once such as a routing method I attached these to the .run () method of my main module/app.
You could separate your models into separate modules if you needed to structure your app that way.

Resources