1

У меня есть директива, которая включает изображение с правом щелчка мыши, которое показывает настраиваемое контекстное меню. Когда пользователь нажимает на элемент в этом контекстном меню, я хочу вызвать метод на родительском контроллере. Я установил контекстное меню, используя ng-context-menu от Ian Walter. Когда я нажимаю элемент контекстного меню, я вызываю код в директиве. Однако все, что я пробовал, не позволяет вызвать функцию контроллера. Я уверен, что есть что-то, что я забыл назначить, поскольку я новичок в Angular.Директива AngularJS, не вызывающая функцию в родительской области

Основной вид вызывает директиву следующим образом:

<div id="apptOverlay" ng-controller="apptCtrl as apptCtrl"> 
    <div class="apptList"> 
    <section data-ng-repeat="apptItem in apptCtrl.appointmentList" data-ng-model="apptCtrl.appointmentList" class="apptStaffList"> 
     <my-box appt="apptItem" status-list="apptCtrl.statusList" edit-appt="apptCtrl.editAppt(apptItem)" status-changed="apptCtrl.statusChanged(apptItem)"></my-box> 
    </section> 
    </div> 
</div> 

HTML Директивы является следующее:

<section> 
    <header> 
     <img src="../../images/{{ appt.StatusIcon }}" data-context-menu context-menu-margin-bottom="10" data-target="menu-{{ appt.Id }}" /> 
     <div id="menu-{{ appt.Id }}" class="dropdown position-fixed"> 
      <ul class="dropdown-menu" role="menu"> 
       <li data-ng-repeat="status in statusList" > 
        <a id="status-{{ status.StatusId }}" data-ng-click="changeStatus(this)"> 
         <img title="{{ status.StatusDescription }}" alt="{{ status.StatusDescription }}" src="../../images/{{ status.Icon }}" class="cellImage cellImageSmall" /> 
         {{ status.StatusDescription }} 
        </a> 
       </li> 
      </ul> 
     </div> 
     {{ appt.LastName }}, {{ appt.FirstName }} 
    </header> 
    <article> 
     <ul> 
      <li>Comments: {{ appt.Comment }}</li> 
     </ul> 
    </article> 
</section> 

код Директивы включает в себя следующее:

angular.module('app').directive('myBox', ['$parse', function ($parse) { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      appt: '=appt', 
      editAppt: '&', 
      statusList: '=', 
      statusChanged: '&' 
     }, 
     templateUrl: 'myBox.html', 
     controller: function($scope) { 
      $scope.changeStatus = function (item) { 
       $scope.appt.CurrentStatusId = item.status.StatusId; 
       $scope.statusChanged({ appointment: $scope.appt }); 
      }; 
     } 
    }; 
}]); 

Контроллер включает следующее:

angular.module('app').controller('apptCtrl', ['$scope', function($scope) { 
    var self = this; 
    self.appointmentList = []; 
    self.statusList = []; 

    self.changeStatus = function (appointment) { 
     var id = appointment.Id; 
    }; 
}]); 

В отличие от этого, у меня есть метод двойного щелчка в директиве, который вызывает проблему с функцией в родительском контроллере без проблем, но это использует $ scope. $ Apply() внутри $ elem.on ('dblclick '). Когда я пытаюсь вызвать $ scope. $ Apply() внутри моей функции changeStatus моей директивы, он дает мне ошибку $ apply is in progress.

Я включил свой код в этот Plunkr. Поскольку он является частью более крупного проекта, я попытался извлечь только важные части для этого вопроса. Я попытался вызвать директивную функцию как в контроллере, так и в разделе ссылок с теми же результатами. Я знаю, что контекстное меню не совсем корректно отображается в Plunk, но не думал, что CSS был настолько важен для этого вопроса.

Заранее благодарим за любую помощь!

ответ

1

Использование $ испускают/$ на

http://plnkr.co/edit/WU54jP

angular.module('app').directive('myBox', ['$parse', function ($parse) { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      appt: '=appt', 
      editAppt: '&', 
      statusList: '=', 
      statusChanged: '&' 
     }, 
     templateUrl: 'myBox.html', 
     controller: function($scope) { 
      $scope.changeStatus = function (item) { 
       $scope.appt.CurrentStatusId = item.status.StatusId; 
       $scope.statusChanged({ appointment: $scope.appt }); 
       $scope.$emit('changeStatus', 'Look Ma, No Hands'); 
      // alert('Status changed in directive'); 
      }; 
     }, 
     link: function ($scope, $elem, $attr) { 

      $elem.bind('dblclick', function() { 
       $scope.editAppt($scope.appt); 
      }); 

      $elem.on('dblclick', function() { 
       // Need to do this to set the appointment in the edit box 
       $scope.$apply(); 
      }); 

      ////var fnChangeStatus = $parse($attr.statusChanged); 
      //$scope.changeStatus = function (item) { 
       //$scope.appt.StatusId = item.status.StatusId; 
       //$scope.statusChanged({ appointment: $scope.appt }); 
       //alert('Status changed in directive'); 
       ////fnChangeStatus({ appointment: $scope.appt }); 
      //}; 

      var drawBox = function() { 
       $elem.css({ 
        height: '150px', 
        backgroundColor: '#99ccff' 
       }); 
      }; 

      drawBox(); 
     } 
    }; 
}]); 


angular.module('app').controller('mainCtrl', function($scope){ 
// There is a main controller that has more general code for the entire application 
}); 

angular.module('app').controller('apptCtrl', ['$scope', function($scope) { 
    /**************************************************************************************************** 
     Properties 
    *****************************************************************************************************/ 
    var self = this; 
    self.appointmentList = [{Id: 1, Comment: 'Testing...', LastName: 'Test', FirstName: 'First', StatusId: 1, StatusIcon: 'Scheduled.png'}]; 
    self.statusList = [{StatusId: 1, Icon: 'scheduled.jpg', StatusDescription: 'Scheduled'}, {StatusId: 2, Icon: 'cancelled.jpg', StatusDescription: 'Cancelled'}]; 

    /**************************************************************************************************** 
     Methods 
    *****************************************************************************************************/ 
    self.editAppt = function (appointment) { 
     self.action = 'Edit'; 
     // editing appointment here... 
     alert('Editing box in controller'); 
    }; 
    $scope.$on('changeStatus', function (event, data) { 
     alert(data); 
    }); 

    self.changeStatus = function (appointment) { 
     var id = appointment.Id; 
     // changing status here... 
     alert('Changing status in controller'); 
    }; 
}]); 

объяснение: http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

Смежные вопросы