0

I have accessed my parent scope plenty of times via $scope.$parent, however i am trying to integrate the ui-router within my project and no long have access to $scope.parent

Here's a plunker: http://plnkr.co/edit/hdoXBngnMatk6HKj4fMC?p=preview

Ive created 2 buttons, one with nested view and controller, and one without.. When you click on the button that is not nested:

  • 1: errorBanner is set to true
  • 2: {{myMessage}} gets set a value

However, on click of the button that is nested, {{myMessage}} no longer updates.

app.js

var app = angular.module('plunker', ['ui.router']);

app.config(["$stateProvider", "$urlRouterProvider", function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/index');

    $stateProvider
        .state('index', {
            url: '/index',
            templateUrl: 'view.html'
        })
}]);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

app.controller('nestedController', function($scope) {
  $scope.setValue = function () {
    $scope.$parent.errorBanner = true;
    $scope.$parent.myMessage = 'hey, it updated!';
  }
});

app.controller('nonNestedController', function($scope) {
  $scope.setValue = function () {
    $scope.$parent.errorBanner = true;
    $scope.$parent.myMessage = 'hey, it updated!';
  }
});
Oam Psy
  • 8,555
  • 32
  • 93
  • 157

2 Answers2

1

You should follow dot rule while defining ng-model to avoid $parent annotation. By following dot rule you could get the prototypically inherited scope inside your child controller.

Markup

  <p>Something should appear below on click: </p>
  <div class="hero-banner-error" data-ng-show="model.errorBanner">
      <p>{{ model.myMessage }}</p>
  </div>

Controller

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.model = {};
});

app.controller('nestedController', function($scope) {
  $scope.setValue = function () {
    $scope.model.errorBanner = true;
    $scope.model.myMessage = 'hey, it updated!';
  }
});

app.controller('nonNestedController', function($scope) {
  $scope.setValue = function () {
    $scope.model.errorBanner = true;
    $scope.model.myMessage = 'hey, it updated!';
  }
});

Also don't assign a controller from the view.html itself which has been loaded from state, your state should be like below, and remove ng-controller from view.html

$stateProvider
.state('index', {
  url: '/index',
  templateUrl: 'view.html',
  controller: "nestedController"
})

Plunkr Here

Community
  • 1
  • 1
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
0

Although Pankajs answer feels like the correct one, i have found another way around it.

By simply removing the declaration of the nestedController from my .html file, and declaring it in app.js instead, i can access the $parent $scope:

Old:

$stateProvider
    .state('index', {
        url: '/index',
        templateUrl: 'view.html'
    })

New:

$stateProvider
    .state('index', {
        url: '/index',
        templateUrl: 'view.html',
        controller: 'nestedController'
    })

Updated plunker: http://plnkr.co/edit/hdoXBngnMatk6HKj4fMC?p=preview

Oam Psy
  • 8,555
  • 32
  • 93
  • 157