AngularJS指令未在父范围内调用功能



我有一个指令,其中包含一个带有右鼠标单击事件的图像,显示自定义上下文菜单。当用户单击此上下文菜单中的项目时,我想在父控制器上调用方法。我已经使用Ian Walter的NG-Context-Menu设置了上下文菜单。当我单击上下文菜单项时,我会在指令中调用代码。但是,我尝试过的一切都无法调用控制器的功能。我敢肯定,我忘了分配一些东西,因为我是Angular的新手。

主视图将指令调用如下:

<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。方法。当我尝试调用$scope。$ apply()我指令的changestatus函数中时,它会给我一个" $ apply已经在进行中"错误。

我已经在此plunkr中包含了我的代码。由于它是一个更大的项目的一部分,所以我试图仅提取此问题的重要部分。我尝试在控制器和链接部分中调用指令函数,并以相同的结果为单位。我知道上下文菜单在Plunk中没有正确显示,但认为CSS对这个问题并不重要。

事先感谢您的任何帮助!

使用$ emit/$ on

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/

最新更新