1

I know you may have seen this question before, but is there really an answer for it? I started to doubt it. Simply, I am using controlleras syntax as recommended, I have no problem accessing parent controller members form within the view, but I cannot do it from the constructor function of my child scope. And here is some code from what I am having right now:

    myapp.controller("ParentController", function() {
      this.selectedItem = {
        Id: 1,
        name: 'item1'
      };
      this.setSelectedItem = function(item) {
        this.selectedItem = item;
        //do other stuff
      }
    });
    myapp.controller("ChildController", function() {
      this.onItemChanged = function(newItem) {
        //How can I call the parent controller instance from here 

      }
    });

Also please notice that I want to call the 'updateSelectedItem' function from my child controller in away that the 'this' keyword will refer to the parent controller instance not the child, because I want to change the parent controller instance, so how should I do this?

Zeyad
  • 51
  • 8
  • using nested controllers is really a form of an anti-pattern. Whenever you are nesting content, you should be using a directive. The best controllers will be self contained, and not reliant upon the behavior of outside sources. – Claies Mar 27 '15 at 21:31
  • Using $scope, you could access parent's $scope from child using $scope.$parent. So you may try to attach your method to $scope instead of 'this'. Btw, a better way to share method is to write angular services which acts as "library" – Raphaël Braud Mar 27 '15 at 21:31
  • And, yes, as said by Claies, it's an anti pattern – Raphaël Braud Mar 27 '15 at 21:32
  • Thanks a lot Raphaël, but I am trying to minimize the use of the $scope service because it's not going to be there at 2.0 version(big shock..I know) Also how can I use a service here, given that the 'selectedItem' property is binded to a grid so I need to change it inside the controller – Zeyad Mar 27 '15 at 21:36
  • again, why are you not using a directive for this behavior? – Claies Mar 27 '15 at 22:08
  • Claies I would appreciate if you can provide me with an example or a link that I can read. – Zeyad Mar 27 '15 at 23:58
  • I've created a new directive which contains the child controller logic + the child view, then whenever the current item changes I call a method that is passed form the parent controller to the directive. This does exactly what I need and now I can use this directive in other pages, am i on the right track? – Zeyad Mar 28 '15 at 01:47
  • sounds like the correct way to approach the problem, but you never provided any of the HTML here to know your exact use case. – Claies Mar 28 '15 at 01:58
  • @claies, can you provide a reference to where nested scope is discussed and considered to be an anti-pattern? – New Dev Mar 28 '15 at 05:02
  • Sorry guys, but I am trying to reach a conclusion here. Are we saying that with the 'ControllerAs' syntax there is no way to access the parent controller instance('this')? Given that I don't want to use the $scope service in my controller and I want to nest them like we used to do with the old syntax – Zeyad Mar 28 '15 at 14:29
  • it was discussed in depth in the same video people refer to when they say "a dot is required in ng-model".... http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html – Claies Mar 28 '15 at 15:05
  • I have once answered this question(not sure if it's an exact duplicate) http://stackoverflow.com/questions/26647460/accessing-inherited-scope-with-controller-as-approach/26708204#26708204 – New Dev Mar 28 '15 at 17:36
  • @Claies, was that the "treat scope as write-only" reference in the video? – New Dev Mar 28 '15 at 17:38

1 Answers1

2

To answer your question as clearly as possible, you first must have a bit of background on how the Controller-As syntax actually works.

Using Controller-As does not mean that you are not using $scope. In reality, $scope still exists. Controller-As is shorthand which creates an object on $scope and attaches the properties assigned via this to that object. On the view side, this object is explicitly bound to all the controls. you could still reference $scope.vm.property. However, since $scope is implicit in this scenario, it is not necessary to create a dependency to it.

Accessing the properties of the vm object of the parent controller in a nested scenario is still possible, but only if each controller is referenced by a different name. If your objects are outerScope and innerScope, then inside the HTML template of innerScope, you can still refer to outerScope.someProperty.

If, however, all controllers are named the same (i.e. vm), then the only way to access the parent controller would be through a property of the child scope which is aliased to a $scope property, introducing the $scope dependency.

In practice, whenever you have a controller within another controller, it's much cleaner for the innermost item to be a directive which wraps its own content, and explicitly defines which variables it needs through an Isolate Scope. However, whenever this is not necessary, the fallback should be for inner controllers to be named uniquely from outer controllers.

Claies
  • 22,124
  • 4
  • 53
  • 77
  • I really appreciate the detailed answer Claris, thanks a lot. I am aware that the Controller-As syntax is not a substitute for the $scope service, but following this syntax will facilitate the transition whenever you migrate to AngularJs v2.0, where the $scope service is not going to be there. Also is there a way to access the properties of the vm object of the parent controller in a nested scenario but form within the child controller itself not from the HTML template? – Zeyad Mar 28 '15 at 23:42
  • not without doing something like `$broadcast`, which is again going to introduce `$scope`. this again leads back to directives, where the directive can have a parameter which is set by the parent controller to be passed to the isolate scope. – Claies Mar 29 '15 at 00:30
  • Thank you Claris, this is much more clear for me right now and I believe this discussion will be useful for many others as well – Zeyad Mar 29 '15 at 10:20