如何触发指令中定义的范围函数
How to trigger a scope function defined inside a Directive
我在我的Angular应用程序中使用了一个仪表板框架,它有很多指令。
在 main 指令中,有一些范围函数使用 ng-click 从 html 模板调用,例如,当用户通过下拉菜单将小部件添加到仪表板时:
<div class="btn-group" ng-if="options.widgetButtons">
<button ng-repeat="widget in widgetDefs"
ng-click="addWidgetInternal($event, widget);" type="button" class="btn btn-primary">
{{widget.name}}
</button>
</div>
但是,我希望能够从我的主控制器代码调用addWidgetInternal()
。
例如,在处理 drop 事件时,我想通过调用 addWidgetInternal
来添加新的小部件:
(function () {
'use strict';
angular.module('rage')
.controller('MainCtrl',
['$scope', '$interval', '$window', 'widgetDefinitions',
'defaultWidgets', 'gadgetInitService', initOptions]);
function initOptions($scope, $interval, $window, widgetDefinitions, defaultWidgets, gadgetInitService) {
this.userName = 'Bob';
this.userRole = 'Risk Analyst';
this.descriptionText = 'Risk Engine';
$scope.dashboardOptions = {
widgetDefinitions: widgetDefinitions,
defaultWidgets: defaultWidgets,
storage: $window.localStorage,
storageId: 'rage.ui',
};
// DRAG AND DROP EVENTS
$scope.handleDrop = function () {
// $scope.addWidgetInternal(); // *** CANNOT MAKE THIS CALL DIRECTLY TO OTHER DIRECTIVE !
// **** UPDATE: a work-around to access scope function in 'dashboard' directive
angular.element(document.getElementById('dash')).scope().addWidgetInternal();
}
}
})();
但是我在调用上面的$scope.addWidgetInternal()
时出现错误:
TypeError: undefined is not a function
以下是主仪表板指令的一个片段 - 特别是link
函数:
link: function (scope) {
scope.widgetDefs = new WidgetDefCollection(scope.options.widgetDefinitions);
scope.addWidgetInternal = function (event, widgetDef) {
event.preventDefault();
scope.addWidget(widgetDef);
};
}
可丢弃指令如下:
.directive('droppable', function () {
return {
restrict: 'A',
scope: {
drop: '&',
},
require: '?dashboard', // 'dashboard' directive is optionally requested; see 'drop' below
link: function (scope, element, attributes, dashboardCtrl) {
var el = element[0];
el.addEventListener('drop', function (e) {
if (e.preventDefault) { e.preventDefault(); }
this.classList.remove('over');
var item = document.getElementById(e.dataTransfer.getData('Text'));
this.appendChild(item.cloneNode(true));
// call the drop function passed in from the dashboard.html 'drop' attribute
scope.$apply(function (scope) {
var fn = scope.drop();
if ('undefined' !== typeof fn) {
fn(e); // PASS THE EVENT TO CALLING FUNCTION
}
});
return false;
}, false);
}
}
});
这是我放置可放置和仪表板指令的仪表板.html视图:
<div class="col-lg-12" data-droppable drop="handleDrop">
<div id="dash" dashboard="dashboardOptions" class="dashboard-container"></div>
</div>
我正在使用的可拖动指令放置在<img>
中,如下所示(因此,上述控制器代码中提到的 drop 事件):
<tr>
<td >
<img data-draggable id="chart_gridhier" src="images/chart_gridhier.jpg" title="TreeGrid" alt="Hierarchy Grid" width="80" height="95">
</td>
<td><img data-draggable "id="chart_area" src="images/chart_area.jpg" title="Area Chart" alt="Area Chart" width="80" height="95"></td>
</tr>
底线:我需要从控制器触发它,而不是从 html 视图模板文件触发ng-click="addWidgetInternal($event, widget);"
。
****更新****我最终将一些拖放指令逻辑移植到仪表板指令代码中。这样,我可以在与仪表板小组件定义相同的范围内处理 DROP 事件。以下是 dashboard
指令中更新的链接代码:
link: function (scope, element) {
// handle drop event from the gadgets drag-drop operation (see gadgets-include.html)
var el = element[0];
el.ondrop = function (e) {
e.dataTransfer.dropEffect = 'move';
var item = document.getElementById(e.dataTransfer.getData('text'));
this.appendChild(item.cloneNode(true));
var newWidget = _.findWhere(scope.widgetDefs, { name: item.id });
// This will add the new widget div to the dashboard
scope.addWidgetInternal(e, newWidget);
};
}
问候
鲍勃
这通常不是实现此目的的强烈建议方法,但我发现这很方便的边缘情况 - 尤其是在集成 Angular 之外的代码时。
我制作了一个代码的轻量级版本小提琴,以提供一个工作演示,您可以随意从那里进行构建。基本上,我通过 id 抓取您的元素并"挖掘"它的作用域,然后调用 scope 函数。在我的示例中,我称您的chart_area
为:
angular
.element(document.getElementById('dash')).scope().addWidgetInternal();
.scope()
.addWidgetInternal(message);
在这种情况下,message
只是我从 UI 发送并在指令中注销addWidgetInternal()
注销的字符串,从控制器调用
JSFiddle Link
- 正在全局范围中查找JavaScript函数
- ES6是否引入了一种机制来生成块范围的函数语句(而不是表达式)
- 可以't访问JavaScript函数范围中的变量
- 在 Angular 指令中,如何进行回调,其中函数名称位于父范围的变量中
- 我怎样才能创建一个函数expr;t继承词法范围
- 获取给定JavaScript范围内的解析函数
- 为什么在javascript中的模块模式中实现Lazy函数时范围会发生变化
- 如何在JavaScript中使用此函数对范围内的所有数字求和
- 构造函数函数中的自执行函数的OO上下文/范围
- javascript和jQuery的嵌套对象函数中的变量范围
- 对象内部函数内的对象文本的范围
- JavaScript 函数变量范围问题
- 如何触发指令中定义的范围函数
- 范围函数角度的右设置
- 角度控制器范围项作为范围函数的子项
- 在 Angular 指令中的事件处理程序中调用范围函数
- Angular JS 如何从指令模板内容事件调用指令范围函数
- 如何使用混合参数调用父级的范围函数
- 如何从带有参数的指令中调用角度控制器范围函数
- 为什么我的范围函数显示一个未定义的值后,循环应该已经关闭