0

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

2 Answers 2

2

Change mode to =mode to enable two way data-binding, @ is passing value as string.

scope: {
    mode: '=mode',  
    id: '@id'
}, 
Sign up to request clarification or add additional context in comments.

Comments

1
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.

5 Comments

ok, i changed the @ sign with = for two-way binding, but my real question was: why do I have to add scope.$parent.$parent.current.mode to change the mode? shouldn't it be $parent.current.mode?
it depends if you had some intermediary levels, like an ng-if would have a layer. By the way you shouldn't do this because with what i posted you don't need it anymore.
I'm reading about $watch...don't I need it for the $watch expression?
No the = mean two way binding, if you write to scope.mode, it will write to current.mode since they're bound. you will need : $scope.$watch(function(){return $scope.current.mode;}, function(newValue){//process goes here});
Thank you, that helped me a lot to understand how to achieve something like this

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.