How to pass data to Controller

436 views
Skip to first unread message

Koen Jans

unread,
Aug 9, 2013, 2:51:55 AM8/9/13
to ang...@googlegroups.com
Hi All,


I'm stating to learn AngularJS, coming from a lot of different MV* frameworks.
I like the framework, however I'm having trouble with passing data between Controllers.

Suppose I have a screen with some input (input.html) and a controller, let's say InputCtrl.
There's a button on this view which takes you to another screen, let's say approve (approve.html) with a controller ApproveCtrl.
This ApproveCtrl needs data from the InputCtrl. This seems like a very common scenario in bigger applications.


In my previous MV* frameworks, this would be handled like (pseudo-code):

          var self = this;
     onClick = function(){
              var approveCtrl = DI.resolve(ApproveCtrl);
       approveCtrl.property1 = 
self.property1;
       approveCtrl.property1 = self.property2;
       
self.router.show(approveCtrl);              
}
  • It would work like Controller- first.
    You create the controller first, having a chance to put it in the right state; afterwards the View gets created.

Now, in AngularJS, i'm handling this like:

     var self = this;
     onClick = function(){
              self.$locationService.path('approve');       
}
  • This works like View-first.
    You say to which view / route to navigate, the Controller gets created by the framework.

I find it hard to control the state of the created Controller and pass data to it.
I've seen and tried following approaches, but all have it's own issues in my opinion:
  1. Inject a shared service into InputCtrl & ApproveCtrl and put all data to be shared on this service
    • This looks like a dirty work-around; the state in the shared service becomes global state, while I just need it to pass data to the ApproveCtrl 
    • The lifetime of this shared service is way longer than what I need it for - just to pass data to the ApproveCtrl 
  2. Pass the data in $routeParams
    • This gets quite messy when having the pass a lot of parameters
  3. Use $scope events
    • Conceptually, this is not something I would use events for - I just need to pass data to the ApproveCtrl, nothing event-ish
    • This is quite cumbersome; I have to send an event to the parent first, that would then broadcast it to it's children

Am I missing something here? Am I creating too many small Controllers?
Am I trying to hold on to habits from other frameworks too much here?


Thanks for your time,
Koen

Chan Leung

unread,
Aug 9, 2013, 11:04:23 AM8/9/13
to ang...@googlegroups.com
Hi,

Let me know if I understand your problem.

You have a page with a master ctrl which have 2 different view loaded into the div.

<div ng-controller='masterCtrl'>
     <div ng-view>
         ....load some other view with controllerA for view 1 and controllerB for view 2.....
     </div>
</div>

In view1 with controllerA you have a button that takes you to view2 with controllerB.

You question is how to pass data from controllerA to controllerB?

If that is the case, why don't you store the share data to masterCtrl and have controllerB put a watch on that data

var controllerA = function($scope){
   $scope.dataA = {......}

    $scope.click = function(){
       $scope.$parent.shareData = $scope.dataA;
       window.location = ' go to view 2';
    }
}

var controllerB = function($scope){
   $scope.$watch($scope.$parent.shareData, function(newValue, oldValue){
      ..do something to the data....
   }
}

var masterCtrl = function($scope){
   $scope.shareData = {};  
}

I believe this is what you want.

Chan

Martin Alix

unread,
Aug 11, 2013, 12:49:19 AM8/11/13
to ang...@googlegroups.com
You might want to take a look at https://github.com/angular-ui/ui-router, it has been designed with your use case in mind, particularly $routeParams and transitionTo

Ashit Vora

unread,
Aug 11, 2013, 1:30:51 AM8/11/13
to ang...@googlegroups.com
Like Chan said, you can either have a parent controller and have the property that you want to share in the parent controller.
So when you save the value and redirect, save in parent controller's scope property so it will be accessible from another controller which is again a child of the parent controller.

Another option that I use always and prefer is...

Create a service and inject that service in both the controllers.
Services are like singleton and instantiated only once.
You can save your data in a property from Controller one and then access it from Controller two.

app.factory("MyService", function(){ return sharedData; });

app.controller("FirstCtrl", function($scope, MyService){ 
    // save data
    MyService.sharedData = your data;

   // redirect to view that uses SecondCtrl
});

app.controller("SecondCtrl", function($scope, MyService){
  // get data
  var data = MyService.sharedData;
});


I hope this makes sense.

Koen Jans

unread,
Aug 12, 2013, 1:23:41 PM8/12/13
to ang...@googlegroups.com
Looks interesting, I 'll look into this.
I am kind of surprised to have to resort to external framework additions for something I consider quite trivial.

Op zondag 11 augustus 2013 06:49:19 UTC+2 schreef Martin Alix:

Koen Jans

unread,
Aug 12, 2013, 1:25:46 PM8/12/13
to ang...@googlegroups.com
Thanks for the suggestion;

But as I mentioned in my initial question, I do not like this technique:

The state in the shared service becomes a global state, while I just need it to pass data to the ApproveCtrl.
This service will live on forever, while I just need it to pass parameters.



Op zondag 11 augustus 2013 07:30:51 UTC+2 schreef Ashit Vora:

Kai Groner

unread,
Aug 12, 2013, 2:02:59 PM8/12/13
to ang...@googlegroups.com
Hi Koen,

You might be aware that 1.1.x added a resolve property to $route definitions, it allows passing locally defined dependencies to a controller.  I think ng-controller could use a similar mechanism, but it hasn't caught up yet.

I just posted some thoughts on this (and the general problem of passing data to controllers) in response to "Access an instance config from a directive in a controller? Or am I barking up the wrong tree?", https://groups.google.com/d/msg/angular/6YicM4nOe4k/5byUzxUz2pUJ


Kai




--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages