CoffeeScript - 不允许在 Angular 表达式中引用 DOM 节点

Posted

技术标签:

【中文标题】CoffeeScript - 不允许在 Angular 表达式中引用 DOM 节点【英文标题】:CoffeeScript - Referencing DOM nodes in Angular expressions is disallowed 【发布时间】:2014-07-13 08:39:03 【问题描述】:

我的主要问题很简单:

我在控制器或指令中进行 DOM 操作时遇到错误,但是该功能运行良好。

Error: [$parse:isecdom] Referencing DOM nodes in Angular expressions is disallowed! Expression: open()

我想忽略这些错误,并确认这样做是安全的,从 功能 角度(不是设计角度)

为了简单起见,我希望能简单地回答这个问题,而不必质疑我是否需要这样做。


现在,如果有人确实想更详细地讨论,我有这个要点: https://gist.github.com/kosz/04f916a5725d85045be5(依赖项:angular、jquery、jquery ui 对话框) 使用我目前遇到这种行为的代码。

到目前为止,我已经尽了最大的努力来消除这个错误,并且根据我阅读的内容和文档,指令中似乎鼓励使用角度进行 dom 操作。

所以我已经使代码与指令一起工作,但是,它仍然抛出错误!?

如您所见,如果用户想要编辑,我正在使用 Jquery UI 并为每个列表项显示它。我没有直接操作 dom,但是,我需要一种方法来控制 jQuery ui 对话框的关闭/打开事件,这不会使 Angular 用错误填充我的控制台。

非常感谢您对此的任何见解。

请注意,我知道有角度的 ui 引导模式,在这种特殊情况下我不能使用它。

【问题讨论】:

这是针对 dom 操作的标准角度错误:错误:[$parse:isecdom] 不允许在 Angular 表达式中引用 DOM 节点!表达式: open() 。编辑问题以包含此信息 您是否尝试过在函数中(在表达式之外)调用您的 DOM 操作功能?根据documentation,该检查仅对 Angular 表达式中的对象索引和函数调用执行 您是否尝试过使用常规箭头-> 而不是粗箭头=> 绑定/创建scope.open? 【参考方案1】:

如错误所示,Angular 不允许在表达式中访问 DOM 节点。

如果未指定,CoffeeScript 将使用隐式 return

这意味着例如您的代码中的scope.open 函数将:

return element.dialog('open');

Angular 会检测到这一点并抛出错误。

如果你添加一个明确的return 它应该可以解决问题:

scope.open = =>
  element.dialog('open') 
  return true

【讨论】:

非常感谢。这行得通。有点难过,因为 angular 抱怨这样的事情,但对答案很满意。再次感谢。如果这个网站允许的话,我会竖起大拇指你的回答 我自己永远也想不通。非常感谢分享。 coffeescript 的建议非常有帮助,非常感谢【参考方案2】:

尽管公认的答案是正确的,但我还是想分享我的经验,因为事实证明这是一个不同的问题。事实上,我遇到了同样的问题,但我实际上并没有从我的函数中返回任何东西(并且没有使用 CoffeeScript),所以我有点困惑并努力寻找解决方案。

就我而言,问题似乎是我将 DOM 节点作为参数传递给函数,如下所示:

<span ng-mouseenter="doSomething($event.currentTarget)"></span>

这里被证明是一个解决方案是更改上述代码以仅传递事件而直接传递节点:

<span ng-mouseenter="doSomething($event)"></span>

然后在控制器/指令/任何类似的地方获取节点:

doSomething = function(evt)
    var elem = evt.currentTarget;
    // do something with this element...
;

【讨论】:

【参考方案3】:

在表达式尝试访问 DOM 节点时发生。

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

此检查仅对 Angular 表达式中的对象索引和函数调用执行。这些是开发人员更难守卫的地方。点状成员访问(例如 a.b.c)不执行此检查 - 由开发人员决定不要直接在作用域链上公开这些敏感和强大的对象。

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

$parse:isecdom 错误也会在事件处理程序调用返回 DOM 节点的函数时发生。

<button ng-click="iWillReturnDOM()">click me</button>

js:

$scope.iWillReturnDOM = function() 
  return someDomNode;

要解决此问题,请避免从事件处理程序返回 DOM 节点。

注意:此错误通常意味着您正在从控制器访问 DOM,这通常表明编码风格不佳,违反了关注点分离。

CoffeeScript 中的隐式返回

使用 CoffeeScript 时,此错误可能会更频繁地发生,它具有称为隐式返回的功能。当函数没有明确的 return 语句时,此语言功能返回函数中最后一个取消引用的对象。

这种情况下的解决方案是添加显式返回语句。对于example return 函数为false。

Error: $parse:isecdom Referencing a DOM node in Expression

【讨论】:

以上是关于CoffeeScript - 不允许在 Angular 表达式中引用 DOM 节点的主要内容,如果未能解决你的问题,请参考以下文章

如何将 jest 与 coffeescript 和 ES6/ES2015 一起使用(例如通过 Babel)?

AngularJS、REST、C# 服务、405 - 不允许发布方法

如何将 Coffeescript 2 视为 JSX? (网络包/通天塔)

Embedded Coffeescript (ECO) 模板中的注释

如何不封装 Coffeescript

将 CoffeeScript 项目转换为 JavaScript(不缩小)? [关闭]