4

Here is the thing:

<div ng-controller="controller1">
   <div ng-controller="controller2" ng-init="controller2.someMethod(controller1.Data.someId)">
      {{something}}
   </div>
</div>

For some reason I can't access controller1.Data.someId in the div of the other controller, but I really need to pass this ID to the other controller's method.

How could this be possibly done?

UPDATE:

<div ng-controller="routesController as routesCtrl">
    <div class="ps-top-space-1" ng-controller="routeController as routeCtrl" ng-init="loadFromRouteInfoScreen(routesCtrl.RoutesData.apiRouteInfoResponse)">
        <ons-button modifier="large" ng-click="routeCtrl.addTickAndRouteRating()">Rate route or Add tick...</ons-button>
    </div>
</div>

Where routesCtrl.RoutesData.apiRouteInfoResponse is set in the routesController and should have a data object with the route_id. My method loadFromRouteInfoScreen(route_id) is triggering some other functions (and a console.log).

Community
  • 1
  • 1
Jozef Kétyi
  • 147
  • 2
  • 11
  • With the setup above, controller2's $scope inherits from controller1's $scope. So if you set in controller1 $scope.value = 7, then you can access it from controller2 $scope.value. – Jim Cote Jan 12 '17 at 21:45
  • Create a service to share data between controllers, it can get messy working with parent/child relationships in controllers. – MannfromReno Jan 12 '17 at 21:55
  • It turns out that my only problem is that if I pass the whole object (controller1.Data.apiResponse) it will be passed to the method correctly, however I only need "controller1.Data.apiResponse.data.someId" from it, which I can't get for some reason... – Jozef Kétyi Jan 12 '17 at 22:23
  • Can you log `controller1.Data.apiResponse` and show the structure in your question? – Alex K Jan 12 '17 at 22:25
  • Yes and I see the data object with the id property: abortDeferer Deferred { promise=Promise, resolve=function(), reject=function(), more...} data Object { route_id=139, route_name="Fialová", route_build_date_iso="2015-01-12", more...} error – Jozef Kétyi Jan 12 '17 at 22:35
  • You need to edit the question to add that code. There are serious problems with your code including that you are manufacturing a promise using `Promise` which is not integrated with the AngularJS framework. – georgeawg Jan 12 '17 at 22:47
  • Changes to scope made with the `.then` method of a JavaScript Promise will not be seen until something triggers an AngularJS digest cycle. – georgeawg Jan 12 '17 at 22:51
  • I have edited my question with real code (not the whole one though).. – Jozef Kétyi Jan 12 '17 at 23:17
  • Hehh, well right now I don't know which answer to pick as the correct one, as it seems that more are OK. However I found the problem, for some reason the data in apiRouteInfoResponse wasn't accessible. What I did was that I've assigned the required route_id into RoutesData.apiRouteInfoResponse.routeId and I was able to send this id from controller1 into controller2... My bad that it didn't work before :( – Jozef Kétyi Jan 14 '17 at 00:19

3 Answers3

1

There is a typo on the first controller- ng-contoller="controller1". If that gets corrected, then the controller will be created correctly, and controller2 will inherit the scope from controller1 (refer to the Angular docs for Scope inheritance) and see the example below.

Also note that in the HTML we don't need to reference the controller variable - omit that object, since we can access properties on the scope directly. So instead of:

<div ng-controller="controller2" ng-init="controller2.someMethod(controller1.Data.someId)">

Do this:

<div ng-controller="controller2" ng-init="someMethod(Data.someId)">

var app = angular.module('app', []);
app.controller('controller1', ['$scope',
  function($scope) {
    $scope.Data = {
      someId: 3
    };
    $scope.something = 'something text';
  }
]);
app.controller('controller2', ['$scope',
  function($scope) {
    $scope.someMethod = function(id) {
      console.log('id: ', id, ' $scope.Data: ', $scope.Data);
    };
  }
]);
<script src="https://code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="controller1">
    <div ng-controller="controller2" ng-init="someMethod(Data.someId)">
      {{something}}
    </div>
  </div>
</div>

Update:

Since you updated your question to have more detail (e.g. Controllers specified with an alias), I have taken that angular HTML and alterred it to the code below. Notice how you don't really need to reference the aliases within the inline calls?

And note that I did simplify the button so we don't need an extra directive for that.

var app = angular.module('app', []);
app.controller('routesController', ['$scope',
  function($scope) {
    console.log('routesController created');
    $scope.RoutesData = {
      apiRouteInfoResponse: "43 miles"
    };
    $scope.something = 'something text';
    $scope.addTickAndRouteRating = function() {
      console.log('addTickAndRouteRating() called');
    };
    $scope.loadFromRouteInfoScreen = function(response) {
      console.log('loadFromRouteInfoScreen() called - response:',response);
    };
  }
]);
app.controller('routeController', ['$scope',
  function($scope) {
    $scope.someMethod = function(id) {
      console.log('id: ', id, ' $scope.Data: ', $scope.Data);
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="routesController as routesCtrl">
    <div class="ps-top-space-1" ng-controller="routeController as routeCtrl" ng-init="loadFromRouteInfoScreen(RoutesData.apiRouteInfoResponse)">
      <button modifier="large" ng-click="addTickAndRouteRating()">Rate route or Add tick...</button>
    </div>
  </div>
</div>
Community
  • 1
  • 1
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
0
<!-- REPLACE
<div ng-contoller="controller1">
-->
<div ng-controller="controller1">
<!--        ^ --- spell controller correctly --> 
   <div ng-controller="controller2" ng-init="someMethod(Data.someId)">
      {{something}}
   </div>
</div>

As long as there is no Data property on the child scope, it will prototypically inherit from the parent scope.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • I think there is Data property on the controller2 (at least "someMethod" is setting triggering functions for response data) – Jozef Kétyi Jan 12 '17 at 22:19
0

You can use the Controller As syntax to make it clear whether you're referencing a parent or child variable in a nested scope.

var myApp = angular.module('myApp', []);

myApp.controller('controller1', function() {
  var vm = this;

  this.something = 'hello';

  vm.Data = {
    someId: 123
  };
});

myApp.controller('controller2', function() {
  var vm = this;

  this.something = 'world';

  this.someMethod = function(someId) {
    console.log('someId: ' + someId);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">

  <div ng-controller="controller1 as ctrl1">
    <div ng-controller="controller2 as ctrl2"
         ng-init="ctrl2.someMethod(ctrl1.Data.someId)">
      {{ctrl1.something}} {{ctrl2.something}}
    </div>
  </div>

</div>
Alex K
  • 1,937
  • 11
  • 12