angular.element 与 document.getElementById 或带有旋转(忙)控件的 jQuery 选择器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17230242/
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-08-26 18:40:47  来源:igfitidea点击:

angular.element vs document.getElementById or jQuery selector with spin (busy) control

jqueryangularjs

提问by irascian

I'm using the "Angularised" version of the Spin control, as documented here: http://blog.xvitcoder.com/adding-a-weel-progress-indicator-to-your-angularjs-application/

我正在使用 Spin 控件的“Angularised”版本,如此处所述:http: //blog.xvitcoder.com/adding-a-weel-progress-indicator-to-your-angularjs-application/

One of the things I don't like about the shown solution is the use of jQuery in the service that effectively attaches the spin control to the DOM element. I would prefer to use angular constructs to access the element. I'd also like to avoid "hard-coding" the id of the element that the spinner needs to attach to within the service and instead use a directive that sets the id in the service (singleton) so that other users of the service or the service itself don't need to know that.

我不喜欢显示的解决方案的一件事是在服务中使用 jQuery,它有效地将自旋控件附加到 DOM 元素。我更喜欢使用角度构造来访问元素。我还想避免对微调器需要在服务中附加到的元素的 id 进行“硬编码”,而是使用在服务(单例)中设置 id 的指令,以便该服务的其他用户或服务本身不需要知道这一点。

I'm struggling with what angular.element gives us vs what document.getElementById on the same element id gives us. eg. This works:

我正在努力解决 angular.element 为我们提供的内容与相同元素 id 上的 document.getElementById 为我们提供的内容。例如。这有效:

  var target = document.getElementById('appBusyIndicator');

None of these do:

这些都没有:

  var target = angular.element('#appBusyIndicator');
  var target = angular.element('appBusyIndicator');

I'm clearly doing something that should be fairly obvious wrong! Can any one help?

我显然在做一些应该是相当明显错误的事情!任何人都可以帮忙吗?

Assuming I can get the above working, I have a similar problem with trying to replace jQuery access to the element: eg $(target).fadeIn('fast');works angular.element('#appBusyIndicator').fadeIn('fast')or angular.element('appBusyIndicator').fadeIn('fast')doesn't

假设我可以完成上述工作,我在尝试替换对元素的 jQuery 访问时遇到了类似的问题:例如$(target).fadeIn('fast');有效 angular.element('#appBusyIndicator').fadeIn('fast')angular.element('appBusyIndicator').fadeIn('fast')无效

Can someone point me to a good example of documentation that clarifies use of an Angular "element" vs the DOM element? Angular obviously "wraps" the element with its own properties, methods etc but it's often hard to get the original value. For example if I have an <input type='number'>field and I want to access the original contents that are visible in the ui when the user types "--" (without the quotes) I get nothing, presumably because the "type=number" means Angular is rejecting the input even though it's visible in the UI and I want to see it so I can test for it and clear it down.

有人能给我指出一个很好的文档示例,它阐明了 Angular“元素”与 DOM 元素的使用?Angular 显然用自己的属性、方法等“包装”了元素,但通常很难获得原始值。例如,如果我有一个<input type='number'>字段,并且我想在用户键入“--”(不带引号)时访问 ui 中可见的原始内容,我什么也得不到,大概是因为“type=number”意味着 Angular 拒绝输入即使它在 UI 中可见并且我想看到它,以便我可以测试它并清除它。

Any pointers/answers appreciated.

任何指针/答案表示赞赏。

Thanks.

谢谢。

回答by kaiser

It canwork like that:

可以这样工作:

var myElement = angular.element( document.querySelector( '#some-id' ) );

You wrap the Document.querySelector()native Javascriptcall into the angular.element()call. So you always get the element in a jqLiteor jQueryobject, depending whether or not jQueryis available/loaded.

您将本Document.querySelector()机 Javascript调用包装到angular.element()调用中。所以你总是在jqLit​​ejQuery对象中获取元素,这取决于是否jQuery可用/加载。

Official documentation for angular.element:

官方文档angular.element

If jQueryis available, angular.elementis an alias for the jQueryfunction. If jQuery is not available, angular.elementdelegates to Angulars built-in subset of jQuery, that called "jQuery lite" or jqLite.

All element references in Angularare always wrapped with jQueryor jqLite(such as the element argument in a directives compile or link function). They are never raw DOMreferences.

如果jQuery可用,angular.element则是jQuery函数的别名。如果 jQuery 不可用,则angular.element委托给Angular的内置子集jQuery,称为“jQuery lite”或jqLit​​e

中的所有元素引用Angular始终用jQueryjqLite(例如指令编译或链接函数中的元素参数)包装。它们从来都不是原始DOM引用。

In case you do wonder why to use document.querySelector(), please read this answer.

如果您确实想知道为什么要使用document.querySelector(),请阅读此答案

回答by garst

You should read the angular elementdocs if you haven't yet, so you can understand what is supported by jqLite and what not -jqlite is a subset of jquery built into angular.

如果你还没有,你应该阅读 angular elementdocs,这样你就可以理解什么是 jqLit​​e 支持的,什么不是 -jqlite 是内置在 angular 中的 jquery 的一个子集。

Those selectors won't workwith jqLite alone, since selectorsby id are not supported.

这些选择器不能单独使用 jqLit​​e,因为不支持按 id 的选择器

  var target = angular.element('#appBusyIndicator');
  var target = angular.element('appBusyIndicator');

So, either :

所以,要么:

  • you use jqLite alone, more limited than jquery, but enough in most of the situations.
  • or you include the full jQuery lib in your app, and use it like normal jquery, in the places that you really need jquery.
  • 你单独使用 jqLit​​e,比 jquery 更有限,但在大多数情况下足够了。
  • 或者您在您的应用程序中包含完整的 jQuery 库,并在您真正需要 jquery 的地方像普通 jquery 一样使用它。

Edit: Note that jQuery should be loaded beforeangularJS in order to take precedence over jqLite:

编辑:请注意,jQuery 应该angularJS之前加载,以便优先于 jqLit​​e:

Real jQuery always takes precedence over jqLite, provided it was loaded before DOMContentLoaded event fired.

真正的 jQuery 总是优先于 jqLit​​e,前提是它在 DOMContentLoaded 事件触发之前加载。

Edit2: I missed the second part of the question before:

Edit2:我之前错过了问题的第二部分:

The issue with <input type="number">, I thinkit is not an angular issue, it is the intended behaviour of the nativehtml5 number element.

的问题<input type="number">,我认为这不是角度问题,而是原生html5 数字元素的预期行为。

It won't return a non-numeric value even if you try to retrieve it with jquery's .val()or with the raw .valueattribute.

即使您尝试使用 jquery.val()或原始.value属性检索它,它也不会返回非数字值。

回答by Dasun

var target = document.getElementById('appBusyIndicator');

is equal to

等于

var target = $document[0].getElementById('appBusyIndicator');

回答by Thomas Decaux

I don't think it's the right way to use angular. If a framework method doesnt exist, don't create it! This means the framework (here angular) doesnt work this way.

我认为这不是使用 angular 的正确方法。如果框架方法不存在,请不要创建它!这意味着框架(此处为 angular)不能以这种方式工作。

With angular you should not manipulate DOM like this (the jquery way), but use angular helper such as

使用 angular,您不应该像这样操作 DOM(jquery 方式),而是使用 angular helper,例如

<div ng-show="isLoading" class="loader"></div>

Or create your own directive (your own DOM component) in order to have full control on it.

或者创建您自己的指令(您自己的 DOM 组件)以便对其进行完全控制。

BTW, you can see here http://caniuse.com/#search=queryselectorquerySelector is well supported and so can be use safely.

顺便说一句,您可以在这里看到http://caniuse.com/#search=queryselectorquerySelector 得到很好的支持,因此可以安全使用。

回答by Kanchan

If someone using gulp, it show an error if we use document.getElementById()and it suggest to use $document.getElementById()but it doesn't work.

如果有人使用 gulp,如果我们使用它会显示错误document.getElementById()并且它建议使用$document.getElementById()但它不起作用。

Use -

用 -

$document[0].getElementById('id')

回答by Nishant Baranwal

You can access elements using $document ($document need to be injected)

您可以使用 $document 访问元素(需要注入 $document)

var target = $document('#appBusyIndicator');
var target = $document('appBusyIndicator');

or with angular element, the specified elements can be accessed as:

或者使用角度元素,可以通过以下方式访问指定的元素:

var targets = angular.element(document).find('div'); //array of all div
var targets = angular.element(document).find('p');
var target = angular.element(document).find('#appBusyIndicator');

回答by Adamy

You should inject $document in your controller, and use it instead of original document object.

您应该在控制器中注入 $document,并使用它而不是原始文档对象。

var myElement = angular.element($document[0].querySelector('#MyID'))

If you don't need the jquery style element wrap, $document[0].querySelector('#MyID') will give you the DOM object.

如果您不需要 jquery 样式元素换行, $document[0].querySelector('#MyID') 将为您提供 DOM 对象。

回答by susrut316

This worked for me well.

这对我很有效。

angular.forEach(element.find('div'), function(node)
{
  if(node.id == 'someid'){
    //do something
  }
  if(node.className == 'someclass'){
    //do something
  }
});

回答by Rob H

Improvement to kaiser's answer:

改进凯撒的回答:

var myEl = $document.find('#some-id');

Don't forget to inject $documentinto your directive

不要忘记注入$document您的指令

回答by Vishal Anand

Maybe I am too late here but this will work :

也许我来得太晚了,但这会奏效:

var target = angular.element(appBusyIndicator);

Notice, there is no appBusyIndicator, it is plain ID value.

注意,没有appBusyIndicator,它是普通的 ID 值。

What is happening behind the scenes: (assuming it's applied on a div) (taken from angular.js line no : 2769 onwards...)

幕后发生的事情:(假设它应用于 div)(取自 angular.js 行号:2769 起...)

/////////////////////////////////////////////
function JQLite(element) {     //element = div#appBusyIndicator
  if (element instanceof JQLite) {
    return element;
  }

  var argIsString;

  if (isString(element)) {
    element = trim(element);
    argIsString = true;
  }
  if (!(this instanceof JQLite)) {
    if (argIsString && element.charAt(0) != '<') {
      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
    }
    return new JQLite(element);
  }

By default if there is no jQuery on the page, jqLite will be used. The argument is internally understood as an id and corresponding jQuery object is returned.

默认情况下,如果页面上没有 jQuery,将使用 jqLit​​e。该参数在内部被理解为一个 id 并返回相应的 jQuery 对象。