36

I'm getting started with Angular.JS.

I have a number of views that share the same controller. Each view is a step in collecting data that is stored in the controller:

$routeProvider.when('/', {
  templateUrl: 'partials/text.html',
  controller: 'itemSubmitter'
});

$routeProvider.when('/nextThing', {
  templateUrl: 'partials/nextthing.html',
  controller: 'itemSubmitter'
});

The itemSubmitter controller:

$scope.newitem = {
  text: null
}

Here's the first view:

<textarea ng-model="newitem.text" placeholder="Enter some text"></textarea>

<p>Your text is:
{{ newitem.text }}</p>

This works, live updating the 'Your text is:' paragraph.

However when the next view is loaded, {{ newitem.text }} is reset to its default value. How can I make values stored in a controller instance persist across views?

Charles
  • 50,943
  • 13
  • 104
  • 142
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • Can you share the code up to the ng-controller attribute? – plus- Apr 25 '13 at 09:33
  • @plus I've added app.js and the controller. However I do not currently use ng-controller anywhere in my code. My understanding is that app.js routing binds each view to the controller. Should I be using ng-controller? – mikemaccana Apr 25 '13 at 09:42
  • If you need data to persist across views, you could inject `$rootScope` into your controllers and stash it there. – jpsimons Apr 26 '13 at 05:44

1 Answers1

68

Controllers are disposed when changing routes. This is good behavior since you should not rely on controllers to carry data between views. It's best to create a service to handle that data.

See the angular docs on how to use controllers correctly. http://docs.angularjs.org/guide/dev_guide.mvc.understanding_controller

To quote from the docs:

Using Controllers Correctly

In general, a controller shouldn't try to do too much. It should contain only the business logic needed for a single view.

The most common way to keep controllers slim is by encapsulating work that doesn't belong to controllers into services and then using these services in controllers via dependency injection. This is discussed in the Dependency Injection Services sections of this guide.

Do not use controllers for:

  • Any kind of DOM manipulation — Controllers should contain only business logic. DOM manipulation—the presentation logic of an application—is well known for being hard to test. Putting any presentation logic into controllers significantly affects testability of the business logic. Angular offers databinding for automatic DOM manipulation. If you have to perform your own manual DOM manipulation, encapsulate the presentation logic in directives.
  • Input formatting — Use angular form controls instead.
  • Output filtering — Use angular filters instead.
  • To run stateless or stateful code shared across controllers — Use angular services instead.
  • To instantiate or manage the life-cycle of other components (for example, to create service instances).
Bart
  • 17,070
  • 5
  • 61
  • 80
  • That's fairly interesting that this is the accepted approach. I don't mean to get into a discussion about theories and patterns but it would seem one controller per view would be more of a MVVM pattern than a traditional MVC pattern – PW Kad Aug 15 '13 at 18:59
  • 1
    @PW The pattern has little to do with it really. The controller simply should not have the responsibility of keeping/sharing state across views. – Bart Aug 15 '13 at 21:43
  • 2
    As per the documentation you referenced angular states that there should be one controller per view, which goes against a lot of typical MVC type approaches such as ASP.NET MVC – PW Kad Aug 15 '13 at 21:48
  • 1
    Angular isn't really trying to be MVC – http://stackoverflow.com/questions/13329485/mvw-what-does-it-stand-for – Charlie Schliesser May 21 '14 at 21:12