AngularJS 指令未在父作用域上调用函数
AngularJS directive not calling function on parent scope
我有一个指令,其中包含一个带有显示自定义上下文菜单的鼠标右键单击事件的图像。当用户单击此上下文菜单中的项目时,我想调用父控制器上的方法。我已经使用 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;
};
}]);
顺便说一句,我在指令中有一个双击方法可以毫无问题地调用父控制器中的函数,但这在 $elem.on( 'dblclick') 方法。当我尝试在我的指令的 changeStatus 函数中调用 $scope.$apply() 时,它给我一个“$apply already in progress”错误。
我已将我的代码包含在此 Plunkr 中。因为它是一个更大项目的一部分,所以我试图只提取这个问题的重要部分。我尝试在控制器和 link 部分中调用指令函数,结果相同。我知道上下文菜单在 Plunk 中显示不正确,但不认为 CSS 对这个问题那么重要。
在此先感谢您的帮助!
使用 $emit / $on
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/
我有一个指令,其中包含一个带有显示自定义上下文菜单的鼠标右键单击事件的图像。当用户单击此上下文菜单中的项目时,我想调用父控制器上的方法。我已经使用 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;
};
}]);
顺便说一句,我在指令中有一个双击方法可以毫无问题地调用父控制器中的函数,但这在 $elem.on( 'dblclick') 方法。当我尝试在我的指令的 changeStatus 函数中调用 $scope.$apply() 时,它给我一个“$apply already in progress”错误。
我已将我的代码包含在此 Plunkr 中。因为它是一个更大项目的一部分,所以我试图只提取这个问题的重要部分。我尝试在控制器和 link 部分中调用指令函数,结果相同。我知道上下文菜单在 Plunk 中显示不正确,但不认为 CSS 对这个问题那么重要。
在此先感谢您的帮助!
使用 $emit / $on
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/