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

ira*_*ian 155 jquery angularjs

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

我不喜欢所显示的解决方案之一是在服务中使用jQuery,有效地将旋转控件附加到DOM元素.我更喜欢使用角度构造来访问元素.我还想避免"硬编码"spinner需要附加到服务中的元素的id,而是使用一个指令来设置服务中的id(单例),以便服务的其他用户或服务本身不需要知道.

我正在努力使用angular.element给我们与同一元素id上的document.getElementById给出的内容.例如.这有效:

  var target = document.getElementById('appBusyIndicator');
Run Code Online (Sandbox Code Playgroud)

这些都不是:

  var target = angular.element('#appBusyIndicator');
  var target = angular.element('appBusyIndicator');
Run Code Online (Sandbox Code Playgroud)

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

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

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

任何指针/答案赞赏.

谢谢.

kai*_*ser 222

可以这样工作:

var myElement = angular.element( document.querySelector( '#some-id' ) );
Run Code Online (Sandbox Code Playgroud)

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

官方文件angular.element:

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

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

如果你想知道为什么要使用document.querySelector(),请阅读这个答案.

  • 有人会更喜欢document.querySelector('#...')来简单地使用document.getElementById()吗? (41认同)
  • 您也可以在角元素上执行此操作:var elDivParent = angular.element(elem [0] .querySelector('#an-id'));, elem是一个角元素.这样您就可以在元素内搜索.适用于单元测试. (4认同)
  • @Kato [此答案]中的更多信息(http://stackoverflow.com/a/26848360/376483).希望有所帮助. (4认同)

gar*_*rst 48

你应该阅读angular 元素文档,如果你还没有,那么你可以理解jqLit​​e支持什么,-jqlite是内置于angular的jquery的子集.

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

  var target = angular.element('#appBusyIndicator');
  var target = angular.element('appBusyIndicator');
Run Code Online (Sandbox Code Playgroud)

那么,要么:

  • 你单独使用jqLit​​e,比jquery更有限,但在大多数情况下都足够了.
  • 或者你在你的应用程序中包含完整的jQuery lib,并在你真正需要jquery的地方使用它,就像普通的jquery一样.

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

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

编辑2:我之前错过了问题的第二部分:

问题<input type="number">,我认为这不是一个角度问题,它是本 html5数字元素的预期行为.

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

  • 我们有完整的jQuery库 - 否则上面解释的我的$场景将无效.我的问题是为什么$有效,但angular.element没有 - 尽管可以使用完整的jQuery. (2认同)
  • 在我的第二点,还有一些像view $ value,可用于检索元素的内容,但在输入type = number的情况下,用户输入" - ",这是空的.我想在元素上使用类似于$ rawInputValue的属性来查看BEFORE Angular已经介入的内容,因为" - "仍然在UI中,即使我无法在我的指令中以编程方式访问它. (2认同)

Das*_*sun 27

var target = document.getElementById('appBusyIndicator');
Run Code Online (Sandbox Code Playgroud)

等于

var target = $document[0].getElementById('appBusyIndicator');
Run Code Online (Sandbox Code Playgroud)


Tho*_*aux 17

我不认为这是使用角度的正确方法.如果框架方法不存在,请不要创建它!这意味着框架(这里有角度)不会这样工作.

使用angular你不应该像这样操纵DOM(jquery方式),但是使用角度助手如

<div ng-show="isLoading" class="loader"></div>
Run Code Online (Sandbox Code Playgroud)

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

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

  • 你是绝对正确的.在我认为我需要手动操作DOM的90%以上的情况下,我最终重构代码以消除需求,最后代码更清晰. (2认同)

Kan*_*han 17

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

使用 -

$document[0].getElementById('id')
Run Code Online (Sandbox Code Playgroud)


Nis*_*wal 16

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

var target = $document('#appBusyIndicator');
var target = $document('appBusyIndicator');
Run Code Online (Sandbox Code Playgroud)

或者使用angular元素,可以访问指定的元素:

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');
Run Code Online (Sandbox Code Playgroud)


Ada*_*amy 10

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

var myElement = angular.element($document[0].querySelector('#MyID'))
Run Code Online (Sandbox Code Playgroud)

如果你不需要jquery样式元素换行,$ document [0] .querySelector('#MyID')会给你DOM对象.

  • 当然,如果你不担心在你的unittest中嘲笑$ document,你可以 (5认同)

小智 6

这对我很有用.

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

  • 元素未定义?angular.element.find不是我在没有JQuery的情况下尝试你的函数. (3认同)
  • 请不要这样做.使用其他一个示例.这根本不使用哈希表查找优化. (3认同)