Maintain Model of Scope When Changing Between Views in Angularjs

scope not persisting when changing views

Use the MVC pattern. Services (models) hold you objects, your Controller is just kinda like an a go between between your objects and your views. Most of the work that's done is generally in your models. In angular services are persistent where as controllers get destroyed and recreated when it's no longer in use.

 angular.module('funApp')
.controller('MainCtrl', function ($scope, $http, questions) {
$scope.choice = null;
$scope.addQuestionFeedback = '';
$scope.questions = questions.questions;

$scope.submit = function() {
questions.questions.push(this.AddQuestion);
$scope.addQuestionFeedback = 'Question Successfully Added!';
}
})

.factory('questions', function () {
var questions = [
{
question: "What is your favorite color",
type: "color"
},
{
question: "What is your favorite food",
type: "food"
}
];

return {
questions = questions
}
})

Angular.JS: views sharing same controller, model data resets when changing view

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).

How can I navigate between different views while maintaining views model data in angularjs

If i understand correctly , you want to share some state across two different views of your application. There are many ways to achieve this, as you stated above you can use a service.

var app = angular.module('myApp', []);
app.service('myService', function(){
var data;
this.setData = function(d){
data = d;
}
this.getData = function(){
return data;
}
});

app.controller('myCtrl1', function($scope, myService){
$scope.data = myService.getData();
//do something
});

app.controller('myCtrl2', function($scope, myService){
$scope.data = myService.getData();
//do something
});

Services are singleton, are instantiated once and then cached by angular, everytime you need that specific data you can inject the service and call the methods provided.

Pattern for persisting $scope between routes

I think this is generally sort of true if you have a data heavy application. The more you need functionality for the views the more you end up with in your controllers. For instance I'm using google-maps and ng-grid within an application pretty extensively so all of my controllers contain all the configuration (sometimes functions for label display etc.) inside of controllers. Also the google-maps code I found and have been modifying (MIT Licensed) has a pretty complex JavaScript object that wraps the google maps code and a controller for the directive.

So short version, yes in a data heavy application most of your code ends up in services and the controllers are just hooking up the view to some data from a service, in other cases no. I see what you're saying about persisting scope but I think it's best to leave all the logic that is necessary for the view in the controller (I see this as the views model as opposed to the data model in the service). It just keeps a clear separation of what is going on where and what is affecting what. For example if I need to persist a piece of data between some views I store it in the service (have been considering using a "value" instead since it's more semantically and functionally appropriate but just haven't taken the time to do this re-factor).

Angular JS controller scope, multiple views

You could consider using a service that can be injected into each controller. As the service would essentially be a singleton, the data contained in that service would be shared across the controllers.

You could even assign it to the local $scope for the controllers.

e.g.

var YourApp = angular.module['YourAppName'];

YourApp.factory('YourServiceName', [function(){
return {
var1: '',
var2: '',
var3: ''
}]);

So in your controllers, you can inject 'YourServiceName'. You can assign data to the properties and they would be accessible in other controllers that also have the service injected. If you add to the $scope, changes would be reflected in your view.

so, for 'WorkItemsController', you could have something like:

YourApp.controller('WorkItemsController', ['$scope', 'YourServiceName', function($scope, YourServiceName){
$scope.ServiceData = YourServiceName;
}]);

Therefore in your views you could access ServiceData.var1 etc. and if this data is updated elsewhere via the service, it should automatically reflect in your view.

This way you would be sharing data between scopes without relying on having a shared parent or using $rootscope.

Using the service, you could even move the functionality for retrieving the original data into the service and keep it all together. Data retrieval could still be triggered by a controller, but via a method call on the service, with the service updating its own properties that are accessible in the views.



Related Topics



Leave a reply



Submit