【发布时间】:2014-09-16 09:05:56
【问题描述】:
我正在尝试实现可排序的拖放操作。我尝试了 ng-sortable 和其他一些,但我有一些极端情况,我没有设法根据我的需要调整它们并决定自己做。
我有可拖动、可放置和主 ui-router 视图/控制器的指令。
我正在传递一个函数 ('handleDrop()'),它接受来自控制器的一些参数到 droppable 指令。我希望该函数在从指令调用时更新主视图/控制器范围内的模型。
它工作正常,但抛出 $digest 已经在进行中的错误。
这是因为在指令中,我用$apply 包装了对handleDrop() 的调用,然后在handleDrop 中,我将部分函数包装在另一个$apply 中。显然不正确,但这是我让它工作的唯一方法 - 因为除了错误之外一切正常。
如果我在 handleDrop() 中删除 $apply,则视图只会部分更新(例如,我的列表中附加了一个 li 元素但为空 - 没有相应的数据。
我尝试根据类似问题的答案用 $timeout 替换 handleDrop() 中的 $apply,然后只要我不注入 $timeout 就可以工作,但这显然会抛出“$timeout is not defined”——但它也可以。
如果我将 $timeout 注入控制器,我不会收到这样的错误(如预期的那样),但是 dom 没有再次正确更新..
在我的指令和控制器的剥离版本之下,我认为是重要的部分。 drop() 在 html 中被指定为 handleDrop()。
非常感谢任何关于我做错了什么的帮助
指令:
app.directive('droppable', function() {
return {
scope: {
drop: '&',
bin: '='
},
link: function(scope, element) {
var el = element[0];
el.addEventListener(
'drop',
function(e) {
if (e.stopPropagation) e.stopPropagation();
var item = document.getElementById(e.dataTransfer.getData('text/plain'));
// Putting additional data into variables newStage etc
// call the passed drop function
scope.$apply(function(scope) {
var fn = scope.drop();
if ('undefined' !== typeof fn ) {
fn(item, newStage, prevStage, newIndex);
document.getElementById(someHtmlElementIdIHave).appendChild(item);
}
}
});
return false;
},
false
);
还有控制器:
.controller('funnelCtrl', function ($scope, $state, $http, someObject) {
$scope.handleDrop = function(item, newStage, prevStage, newIndex) {
$http.put('/api/funnel/' + item.id, {some object}).
success(function (data) {
$timeout(function(){
$scope.someObject[newStage].splice(newIndex, 0, item.optyId) ;
$scope.someObect[prevStage].splice(prevIndex,1);
});
}).
error(function (data) {alert('Error Saving');});
};
【问题讨论】:
-
正确的@maurycy,结果我根本不需要任何 $apply,我的错误是在将新元素添加到数组时出错。我仍然对它为什么起作用感到困惑以前使用双重应用..
标签: angularjs angularjs-directive