Search code examples
angularjsangularjs-scopeangular-directive

angularjs - use directive to change parent scope


I'm trying to change a parent scope property from within a directive.

This is the structure of this section of my project (It may help to understand what's going on):

-details
--overview.html
--edit.html
--main.html
-directive
--template.html
--controller.js

directive/controller.js

restrict: 'E'
  scope: {
    mode: '@mode',  
    id: '@id'
  }, 
  replace: true,
  templateUrl: './directive/template.html',
  link: function (scope, element, attrs){
    console.log ("link function scope:", scope);
    console.log ("Parent Scope:", scope.$parent.$parent.current);
  }

directive/template.html:

<div class="Selector">
    <div>
        <input type="checkbox" href="#" class="menu-open" name="menu-open" id="menu-open-{{id}}"/>
        <label class="menu-open-button" for="menu-open-{{id}}">
            <i class="zone-details-current-mode icon-mode-{{mode}}"></i>
            <span class="hamburger hamburger-1"></span>
            <span class="hamburger hamburger-2"></span>
            <span class="hamburger hamburger-3"></span>
        </label>
    </div>
</div>

I call the above directive from details/main.html like below:

<selector mode="{{current.mode}}" id="{{current.ID}}"></selector>

my app.js router configuration is the following:

.config([
  '$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
    $stateProvider.state('app.details', {
      name: 'appDetails',
      url: '/:zoneID',
      views: {
        'appContent': {
          templateUrl: './details/main.html',
          controller: 'mainController'
        }
      }
    }).state('app.details.overview', {
      name: 'appDetailsOverview',
      url: '/overview',
      views: {
        'appContent': {
          templateUrl: './details/main.html',
          controller: 'mainController'
        },
        'zone': {
            templateUrl: './details/overview.html',
            controller: 'mainController'
        }
      }
    }).state('app.details.edit', {
      name: 'appDetailsEdit',
      url: '/edit/day/:timerEditDay',
      views: {
        'appContent': {
          templateUrl: './details/main.html',
          controller: 'mainController'
        },
        'zone': {
          templateUrl: './details/edit.html',
          controller: 'mainController'
        }
      }
    });
    $urlRouterProvider.otherwise('app/myHouse');
  }
]);

What this directive should be able to do, is to change the mode when clicked on a specific button. The mode is inside scope.current, but, to access scope.current, I don't understand why I have to append two $parents.

Also, as a side note, when changing mode, it needs to "refresh" the section with the new mode in place.

Any help with this? how can I use the directive to change the parent scope? Thanks for any help and suggestion


Solution

  • scope: {
        mode: '=mode',  // CHANGE THIS TO =
        id: '@id'
    }, 
     // remove brackets here 
    <selector mode="current.mode" id="{{current.ID}}"></selector>
    // in link function
    scope.mode = [new mode];
    

    About the last point : just use a $scope.$watch in your controller. Or you can go for $on/$emit. Check angular event handling on the net it's pretty easy.