Same data in multiple views using AngularJS
Asked Answered
E

2

7

Maybe there is someone who can help me a little bit. I have to share data between multiple views. Because it is a school project, I have to use AngularJS, but I am new to it and I don't know where to start. The program works as follow:

User (customers) have the possibility to reserve a table in a restaurant. (first page)

User (employees) have the possibility to add orders to a reserved table. (second page)

When a customer reserve a table from the first page, the table is added to the second page so that an employee can add orders to it.

Maybe there is someone who can help me a little bit on my way.

Enviable answered 22/5, 2013 at 8:9 Comment(4)
I'd start with the tutorial in the angular website. it's quite similar: it has a model and it shows the two-way data binding angular provides.Randarandal
The tutorial of AngularJS on the website doens't help me with it. I have searched the web and found that the best way to share data between multiple views is a service. Do you agree with that? Or do you know another way to share data between views?Enviable
yep, that's a good way. for example, if you wanted to have settings in your app, you could put them in the rootScope or in a service. A service is definitely a better solution. however, you are talking about a model and that doesn't look like something you'd put in a service. plain old javascript objects seem useful here but i can't tell you for sure. check this too #16331602 we discusses something simmilar a few days ago :)Randarandal
Thank you, I will read that and think about a good solution for my problem.Enviable
J
6

Since you are new to angularjs an easier approach would be to use $rootScope to share data between your controllers (and the views associated with them).

Here is an example:

angular.module('MyApp', [])

.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: '/views/main.html',
      controller: 'MainCtrl'
    })
    .when('/first-page', {
      templateUrl: '/views/first.html',
      controller: 'FirstCtrl'
    })
    .when('/second-page', {
      templateUrl: '/views/second.html',
      controller: 'SecondCtrl'
    });
}])

.controller('MainCtrl', ['$rootScope', function ($rootScope) {
  // Will be available everywhere in your app
  $rootScope.users = [
    { name: 'Foo' },
    { name: 'Bar' }
  ];
}])

.controller('FirstCtrl', ['$rootScope', '$scope' function ($rootScope, $scope) {
  // Only available inside first.html
  $scope.bazUser = { name: 'Baz' };
  // Add to global
  $rootScope.users.push($scope.bazUser);
}])

.controller('SecondCtrl', ['$rootScope', '$scope' function ($rootScope, $scope) {
  console.log($rootScope.users); // [{ name: 'Foo' }, { name: 'Bar' }, { name: 'Baz' }];
}]);

inside second.html for example

<ul>
  <li ng-repeat="user in users">{{user.name}}</li>
</ul>
Jamshid answered 22/5, 2013 at 14:32 Comment(3)
I am a little bit confused. Why is it that the main controller everywhere available is? Because you use $rootScope, which will tell that the array of users, available for overyone is?Enviable
Sorry if the comments confused you. The Main controller is only called on '/' route (when main.html renders). The $rootScope, you referenced there is like a singleton which you can reference from any other controller. So you can use previously added objects (and their values) accross your app. The benefit is that all the stuff added to $rootScope is also immediately available in all of your views (even when a view has no controllers at all) and you don't have do define it. Services/factories are also always a good choice, especially when your app scales.Jamshid
I think I understand the rootScope now. And it is a good idea to use the rootScope because my app is small and stays small. When I plan to make a bigger app or an app that scales, a service or factorie is a better choice.Enviable
M
12

Services are singletons, so when the service is injected the first time, the code in the factory gets called once. I'm assuming you have a routing table, since you are talking about multiple pages.

If you define this

angular.module('services', [])
.factory('aService', function() {
  var shinyNewServiceInstance;
  //factory function body that constructs shinyNewServiceInstance
  shinyNewServiceInstance = shinyNewServiceInstance || {foo:1};
  return shinyNewServiceInstance;
});

Dependency inject it into your controllers (simplified):

controller('ACtrl', ['aService', function(aService) {
  aService.foo += 1;
}]);

controller('BCtrl', ['aService', function(aService) {
  aService.foo += 1;
}]);

If you examine aService.foo each time you navigate between ACtrl & BCtrl, you will see that the value has been incremented. The logical reason is that the same shinyNewServiceInstance is in your hand, so you can set some properties in the hash from the first page & use it in the second page.

Miles answered 22/5, 2013 at 10:17 Comment(1)
Thank you, I think this can help me a lot!Enviable
J
6

Since you are new to angularjs an easier approach would be to use $rootScope to share data between your controllers (and the views associated with them).

Here is an example:

angular.module('MyApp', [])

.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: '/views/main.html',
      controller: 'MainCtrl'
    })
    .when('/first-page', {
      templateUrl: '/views/first.html',
      controller: 'FirstCtrl'
    })
    .when('/second-page', {
      templateUrl: '/views/second.html',
      controller: 'SecondCtrl'
    });
}])

.controller('MainCtrl', ['$rootScope', function ($rootScope) {
  // Will be available everywhere in your app
  $rootScope.users = [
    { name: 'Foo' },
    { name: 'Bar' }
  ];
}])

.controller('FirstCtrl', ['$rootScope', '$scope' function ($rootScope, $scope) {
  // Only available inside first.html
  $scope.bazUser = { name: 'Baz' };
  // Add to global
  $rootScope.users.push($scope.bazUser);
}])

.controller('SecondCtrl', ['$rootScope', '$scope' function ($rootScope, $scope) {
  console.log($rootScope.users); // [{ name: 'Foo' }, { name: 'Bar' }, { name: 'Baz' }];
}]);

inside second.html for example

<ul>
  <li ng-repeat="user in users">{{user.name}}</li>
</ul>
Jamshid answered 22/5, 2013 at 14:32 Comment(3)
I am a little bit confused. Why is it that the main controller everywhere available is? Because you use $rootScope, which will tell that the array of users, available for overyone is?Enviable
Sorry if the comments confused you. The Main controller is only called on '/' route (when main.html renders). The $rootScope, you referenced there is like a singleton which you can reference from any other controller. So you can use previously added objects (and their values) accross your app. The benefit is that all the stuff added to $rootScope is also immediately available in all of your views (even when a view has no controllers at all) and you don't have do define it. Services/factories are also always a good choice, especially when your app scales.Jamshid
I think I understand the rootScope now. And it is a good idea to use the rootScope because my app is small and stays small. When I plan to make a bigger app or an app that scales, a service or factorie is a better choice.Enviable

© 2022 - 2024 — McMap. All rights reserved.