Search code examples
angularjsangularjs-directiveangularjs-components

changes in directive scope variables don't update the parent scope variables. Angular Js 1.5


This is my controller

 function commentController($stateParams, commentFactory, $rootScope){
  const ctrl = this;
  ctrl.comment = {};
  ctrl.decision = {};
  ctrl.$onInit = function(){
    ctrl.decision.replyVisible = false;
  }

export {commentController}

This is my component

import {commentController} from './comment.controller'

export const commentComponent = 'commentComponent'
export const commentComponentOptions = {
  bindings: {
    post: '<'
  },
  templateUrl: 'blog/src/app/components/post/comment/comment.html',
  controller: ['$stateParams', 'commentFactory', '$rootScope', commentController],
  controllerAs: 'cm'
}

This is my directive

 function showReply(){
  return {
    restrict: 'A',
    scope: {
      collapsed: '<'
    },
    link: function(scope, element, attrs){
      element.on('click', ()=>{
        console.log(`Trying to hide ${scope.collapsed}`);
        scope.collapsed = true
        console.log(`Trying to hide ${scope.collapsed}`);
      })
    }
  }
}

function hideReply(){
  return {
    restrict: 'A',
    scope: {
      collapsed: '<'
    },
    link: function(scope, element, attrs){
      element.on('click', ()=>{
        scope.collapsed = false;
        console.log(`Trying to hide scope.replyVisible is ${scope.collapsed}`);
      })
    }
  }
}

export {showReply, hideReply}

This is my html

 <div class="comment_wrapper">
  <div class="comment" ng-repeat="comment in cm.post.comments">
    <h3>{{comment.author.name}}</h3>
    <a href="" ng-hre="mailto:{{comment.author.email}}"></a>
    <p ng-bind-html="comment.comment"></p>
    <button show-reply collapsed="cm.decision.replyVisible">Reply</button>
    <div class="reply_wrapper" ng-show="cm.decision.replyVisible">
      <label for="name">Name</label>
      <input type="text" id="name" ng-model="cm.comment.author.name">
      <label for="email">Email</label>
      <input type="text" id="email" ng-model="cm.comment.author.email">
      <label for="comment">Comment</label>
      <textarea name="" id="comment" cols="10" rows="5" ng-model="cm.comment.comment"></textarea>
      <button ng-click="cm.reply(comment._id)">Submit</button> <button hide-reply collapsed="cm.decision.replyVisible">Cancel</button>
    </div>
  </div>
</div>

And this is my module

import angular from 'angular'
import {showReply, hideReply} from './comment.directive'
import {commentFactory, commentFactoryFunc} from './comment.factory'
import {commentComponent, commentComponentOptions} from './comment.component'

export const comment = angular.module('comment', [uiRouter])
.factory(commentFactory, ['$http', commentFactoryFunc])
.component(commentComponent, commentComponentOptions)
.directive('showReply', showReply)
.directive('hideReply', hideReply)
.name

Here's what I am trying to do, in my html, I want to show the reply form when someone clicks on the reply button. And since there are multiple comments for with each having a reply form, I can't use the regular ng-click.

The changes made to the scope.collapsed don't get reflected on cm.decision.replyVisible

How do I make this work? I have always been confused about accessing parent controller variables from a directive.


Solution

  • You should use comment.decision.replyVisible instead of cm.decision.replyVisible

    HTML

     <div class="comment_wrapper">
      <div class="comment" ng-repeat="comment in cm.post.comments">
        <h3>{{comment.author.name}}</h3>
        <a href="" ng-hre="mailto:{{comment.author.email}}"></a>
        <p ng-bind-html="comment.comment"></p>
       <button show-reply 
         collapsed="comment.decision.replyVisible">Reply</button>
       <div class="reply_wrapper" ng-show="comment.decision.replyVisible">
         <label for="name">Name</label>
         <input type="text" id="name" ng-model="cm.comment.author.name">
         <label for="email">Email</label>
         <input type="text" id="email" ng-model="cm.comment.author.email">
         <label for="comment">Comment</label>
         <textarea name="" id="comment" cols="10" rows="5" ng-model="cm.comment.comment"></textarea>
         <button ng-click="cm.reply(comment._id)">Submit</button> <button hide-reply collapsed="cm.decision.replyVisible">Cancel</button>
      </div>
     </div>
    </div>