如何向AngularJS中的指令发送DOM函数?

如何向AngularJS中的指令发送DOM函数?,angularjs,dom,angularjs-directive,parse-error,Angularjs,Dom,Angularjs Directive,Parse Error,我遵循了一个关于在Angular中实现拖放的优秀教程,我最初在该教程中找到了作者博客和GitHub代码的链接 当我在我的项目中实现并测试它时,我得到了一个错误: [$parse:isecdom] Referencing DOM nodes in Angular expressions is disallowed! Expression: dropped(dragEl, dropEl) ,问题是我引用了一个函数,该函数将DOM对象作为DOM属性中的参数-发生在这行: <div x-lvl-

我遵循了一个关于在Angular中实现拖放的优秀教程,我最初在该教程中找到了作者博客和GitHub代码的链接

当我在我的项目中实现并测试它时,我得到了一个错误:

[$parse:isecdom] Referencing DOM nodes in Angular expressions is disallowed! Expression: dropped(dragEl, dropEl)
,问题是我引用了一个函数,该函数将DOM对象作为DOM属性中的参数-发生在这行:

<div x-lvl-drop-target='true' x-on-drop='dropped(dragEl, dropEl)'>drop zone</div>

我认为,解决问题的方法相当简单——使用中间对象包装
dragEl
dropEl
,如下所示:

app.value('dropEvent', {dropEl:null, dragEl:null});

app.directive('lvlDropTarget',
  function ($rootScope, dropEvent) {
    return {

 //... 

      link: function (scope, el, attrs, controller) {

 //...

        el.bind("dragover", function (e) {

 //... 

          dropEvent.dragEl = src;
          dropEvent.dropEl = dest;

          scope.onDrop();
        });
 //...

    }
  }
);
在链接功能中:

scope.onDrop({ 
        event : {
          dragEl: src,
          dropEl: dest
        }
      });
在html中:

<div x-lvl-drop-target='true' x-on-drop='dropped(event)'>drop zone</div>
还有工作


或者,您可以在
值中保留有关拖动事件的信息,如下所示:

app.value('dropEvent', {dropEl:null, dragEl:null});

app.directive('lvlDropTarget',
  function ($rootScope, dropEvent) {
    return {

 //... 

      link: function (scope, el, attrs, controller) {

 //...

        el.bind("dragover", function (e) {

 //... 

          dropEvent.dragEl = src;
          dropEvent.dropEl = dest;

          scope.onDrop();
        });
 //...

    }
  }
);
然后在控制器/外部上下文中使用它:

app.controller('MainCtrl', function($scope, dropEvent) {
  $scope.dropped = function(){
    console.log('dropped', dropEvent);
  }
});

10月14日发布了一个问题:

AngularJS现在给出了这个错误:“不允许在角度表达式中引用DOM节点!”,因为:on drop=“controller.drop(dragEl,dropEl)”

提出了以下解决方案:

在较新版本的AngularJS中,返回DOM元素本身会导致$parse:isecdom错误。简单地说,让
丢弃(…)
回调句柄获取元素

因此,如果接受此更改,将修改该指令以返回拖放的元素ID。然后由回调函数执行
document.getElementById

$scope.dropped = function(dragId, dropId) {
  var dragEl = document.getElementById(dragId);
  var dropEl = document.getElementById(dropId);

  console.log(dragEl, dropEl);
}

话虽如此,Angular有充分的理由补充了他们的观点:

AngularJS限制从表达式中访问DOM节点,因为这是执行任意Javascript代码的已知方式

此检查仅对角度表达式中的对象索引和函数调用执行。对于开发者来说,这些地方更难保护。虚线成员访问(如a.b.c)不执行此检查-由开发人员决定不直接在范围链上公开此类敏感和强大的对象

要解决此错误,请避免访问DOM节点


与其试图规避这种保护,我更喜欢你的选择-这鼓励使用,不需要。打得好。

我开始悬赏,因为我在互联网上找不到任何答案。你也在使用jQuery吗。这可能是错误的原因。这些都是很好的建议。最后我使用了
ngDraggable
进行拖动,但这个答案中的信息仍然很有价值。我将由克莱顿决定这是否是公认的答案(如果他给你赏金)
$scope.dropped = function(dragId, dropId) {
  var dragEl = document.getElementById(dragId);
  var dropEl = document.getElementById(dropId);

  console.log(dragEl, dropEl);
}