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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23838497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:39:39  来源:igfitidea点击:

CoffeeScript - Referencing DOM nodes in Angular expressions is disallowed

javascriptjqueryangularjsdomcoffeescript

提问by Cosmin

My main question is simple :

我的主要问题很简单:

I get errors when doing DOM manipulation within Controllers or Directives however, the functionality works perfectly.

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

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

I would like to ignore these errors, and get the confirmation that it is safe to do so, from a functionalityperspective ( not a design perspective )

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

To keep things simple, I would appreciate a simple answer to this question without questioning my need to do this.

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



Now, if anybody does want to discuss in more detail, I have this gist : https://gist.github.com/kosz/04f916a5725d85045be5( dependencies: angular, jquery, jquery ui dialog ) with the code i'm currently experiencing this behaviour in.

现在,如果有人想更详细地讨论,我有这个要点:https: //gist.github.com/kosz/04f916a5725d85045be5(依赖项:angular、jquery、jquery ui dialog)以及我目前正在经历的代码行为在。

I have done my best so far, to get rid of this error, and based on what i read, and the docs, dom manipulation in angular seems to be encouraged in the directives.

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

So I've made the code work with a directive, however, it still throws the error !?

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

As you can see I am using Jquery UI and showing it for each list item, if the user wants to edit. I am not directly manipulating the dom, however, i need a way to control the close/open events of the jQuery ui Dialog, which doesn't make Angular fill my console with errors.

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

Any insight on this is greatly appreciated.

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

Please note that I am aware of the angular ui bootstrap modal, and it's not an option for me to use in this particular scenario.

请注意,我知道 angular ui bootstrap modal,在这个特定场景中我不能使用它。

回答by tasseKATT

As the error states, Angular disallows accessing DOM nodes in expressions.

正如错误所述,Angular 不允许访问表达式中的 DOM 节点。

CoffeeScript uses an implicit returnif none is specified.

return如果没有指定,CoffeeScript 使用隐式。

This means that for example the scope.openfunction in your code will:

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

return element.dialog('open');

Angular will detect this and throw the error.

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

If you add an explicit returnit should solve the issue:

如果添加一个显式return它应该可以解决问题:

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

回答by Nobita

Although the accepted answer is right I'd like to share my experience anyway as it turned out to be a different problem. In fact I had the same issue but I wasn't actually returning anything at all from my function (and not using CoffeeScript) so i was puzzled for a bit and struggled to find a solution.

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

In my case the problem appeared to be that I was passing the DOM node as an argument to the function like so:

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

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

What proved to be a solution here was changing the mentioned code to pass only the event and notthe node directly:

在这里证明是解决方案的是将提到的代码更改为仅传递事件而不是直接传递节点:

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

Then fetch the node in the controller/directive/whatever like so:

然后在控制器/指令/诸如此类的地方获取节点:

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

回答by shilovk

Occurs when an expression attempts to access a DOM node.

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

AngularJS restricts access to DOM nodes from within expressions since it's a known way to execute arbitrary Javascript code.

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

This check is only performed on object index and function calls in Angular expressions. These are places that are harder for the developer to guard. Dotted member access (such as a.b.c) does not perform this check - it's up to the developer to not expose such sensitive and powerful objects directly on the scope chain.

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

To resolve this error, avoid access to DOM nodes.

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

The $parse:isecdomerror also occurs when an event handler invokes a function that returns a DOM node.

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

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

js:

js:

$scope.iWillReturnDOM = function() {
  return someDomNode;
}

To fix this issue, avoid returning DOM nodes from event handlers.

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

Note: This error often means that you are accessing DOM from your controllers, which is usually a sign of poor coding style that violates separation of concerns.

注意:此错误通常意味着您正在从控制器访问 DOM,这通常是违反关注点分离的糟糕编码风格的标志。

Implicit Returns in CoffeeScript

CoffeeScript 中的隐式返回

This error can occur more frequently when using CoffeeScript, which has a feature called implicit returns. This language feature returns the last dereferenced object in the function when the function has no explicit return statement.

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

The solution in this scenario is to add an explicit return statement. For example returnfalse to the function.

这种情况下的解决方案是添加显式返回语句。对于example return错误的功能。

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

错误:$parse:isecdom 在表达式中引用 DOM 节点