0

I have html page with

<div ng-controller="MyCtrl">
  <div ng-view>Some content</div>

  myVar: {{myVar}}
</div>

And angular controller:

myModule.controller('MyCtrl', function($scope, $location) {
   $scope.myVar = false;

   $scope.someAction = function() {
     $location.path('/anotherPath');
     $scope.myVar = true; // changes in controller, but not in view
   }
});

My module is

var myModule = angular.module('myModule', ['ngRoute']).config(function ($routeProvider) {

$routeProvider
     .when('/anotherPath', {
       templateUrl: 'anotherPath.html',
       controller: 'MyCtrl'
     })

     .otherwise({
         redirectTo: '/anotherPath.html'
     })
});

anotherPath.htmlcontains only

<input data-ng-click="someAction()" type="button" class="btn" value="Some action">

After clicking on this input controller changes path, but in view value of myVar is still false. Why?

11
  • Try reversing the statements in someAction Commented Feb 27, 2014 at 8:09
  • Try putting "$scope.myVar = true;" statement before the "$location.path" Commented Feb 27, 2014 at 8:15
  • Does the template from anotherPath have another controller defined for it that would be a child scope and hence doesn't have myVar in its $scope? Commented Feb 27, 2014 at 8:15
  • @StephenKaiser It should inherit from MyCtrl anyway, but it might have redeclared myVar? Commented Feb 27, 2014 at 8:19
  • @RGraham You're right. If he has redeclared it like you pointed out, it overrides the parent scope's value and he will need to use $scope.$parent.myVar. @baxxabit Can you post your template from anotherPath? That might give us more information to help you. Commented Feb 27, 2014 at 8:27

1 Answer 1

2

Here, you have defined your controller twice. Once on the parent div:

<div ng-controller="MyCtrl">

And once on the route for /anotherPath:

$routeProvider
     .when('/anotherPath', {
       templateUrl: 'anotherPath.html',
       controller: 'MyCtrl' <-- This will be assigned to <div ng-view>
     })

Leaving you with something like:

<div ng-controller="MyCtrl">
    <div ng-view ng-controller="MyCtrl">
    </div>
</div>

Therefore, when you call $scope.someAction() you are calling the function defined on the controller assigned to your inner view, rather than the function defined on the parent controller.

You should give your View its own unique controller in the route definition:

Angular:

$routeProvider
     .when('/anotherPath', {
       templateUrl: 'anotherPath.html',
       controller: function($scope) {
           // You don't necessarily need an implementation here
       }
     })

HTML:

<div ng-controller="MyCtrl">
  <div ng-view>Some content</div>

  myVar: {{myVar}}
</div>
Sign up to request clarification or add additional context in comments.

6 Comments

Oh, thanks, I missed this point. I can remove ng-controller declaration from html, will it work?
No, you can't do that either because then myVar would not be defined in any scope. Simply set the controller in your route definition to an empty implementation, it will by default inherit from the parent MyCtrl so you have full access to its functions and variables
Thanks, I'm a newbie in angular :) Is it necessary or can I remove it controller: function($scope) {}
No problem, it's a tough framework to get to grips with! You'd need to check the docs to confirm, but I think a view must have a controller :)
Working as expected now. controller declaration in this case is optional
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.