2013-06-21 65 views
123

我使用的旋转控件的“Angularised”的版本,如记录在这里:http://blog.xvitcoder.com/adding-a-weel-progress-indicator-to-your-angularjs-application/angular.element VS自旋(繁忙)控制的document.getElementById或jQuery选择

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

我很苦恼angular.element给我们什么document.getElementById在相同的元素ID给我们。 例如。这工作:

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

这些都不做:

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

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

假设我能得到上面的工作,我有试图取代jQuery的访问元素类似的问题: 如$(target).fadeIn('fast');工作 angular.element('#appBusyIndicator').fadeIn('fast')angular.element('appBusyIndicator').fadeIn('fast')

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

赞赏任何指针/答案。

谢谢。

+5

angular.element是jQlite对象或jQuery对象如果要加载的jQuery。 – Neil

回答

44

如果您还没有看过角度为element的文档,那么您可以了解jqLit​​e支持哪些内容,以及哪些不是jQueryite是内置于angular中的jquery的子集。通过ID

那些选择将无法​​正常工作单独jqLit​​e,因为选择不被支持。

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

所以,要么:

  • 您使用jqLit​​e独自一人,比jQuery的比较有限,但足以在大多数的情况下。
  • 或者你在你的应用中包含完整的jQuery库,并且像你正常的jquery一样在你真正需要jQuery的地方使用它。

编辑:请注意,jQuery的应该按顺序优先于jqLit​​e加载以前 angularJS:

真正的jQuery总是优先于jqLit​​e,只要它是 DOMContentLoaded事件之前加载解雇。

EDIT2:我错过了问题之前,第二部分:

问题与<input type="number">,我认为它不是一个角度的问题,它是本地 HTML5数量的预期行为元件。

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

+2

我们有完整的jQuery库 - 否则我上面解释的$场景不起作用。我的问题是为什么$工作,但angular.element不 - 即使完整的jQuery可用。 – irascian

+1

您是否在angular.js之前或之后包含jQuery?它应该包括**之前**角。通过id *选择器*做*使用jQuery可用:http://jsbin.com/ohumiy/1/edit – gargc

+1

他们正在另一个指令(即angular.element通过id访问的东西)工作。问题似乎是这个控件通过附加到该元素的方式,尽管我不明白为什么直接应用相同的jQuery等效。直接使用jQuery我的指令HAS有一个结束标记 - 自闭标记不起作用(没有错误只是一个空白屏幕),这使我怀疑控制。 – irascian

196

可以工作那样:

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

您缠绕Document.querySelector() native Javascript呼叫到angular.element()电话。因此,您总是会获取jqLit​​ejQuery对象中的元素,具体取决于jQuery是否可用/已加载。

Official documentation for angular.element:

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

Angular所有元素的引用总是包裹jQuery的jqLite(如在一个指令中的元件参数编译或链接功能)。他们从来没有生DOM参考。

如果您确实想知道为什么要使用document.querySelector(),请参阅this answer

+34

任何理由更喜欢document.querySelector('#...')来简单地使用document.getElementById()吗? – Kato

+4

您也可以对角元素执行此操作:var elDivParent = angular.element(elem [0] .querySelector('#an-id')); elem是一个角元素。这样你可以在元素内搜索。用于单元测试。 – unludo

+3

@Kato更多的信息在[这个答案](http://stackoverflow.com/a/26848360/376483)。希望有所帮助。 – kaiser

16

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

随着角度,你不应该操作DOM这样(jQuery的方式),而用角帮手如

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

或者创建自己的指令(你自己的DOM组件),以便在有完全控制权它。

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

+2

你是对的。在我认为需要手动操作DOM的情况下,90%以上的情况下,我最终重构了代码以删除需求,最终代码更加清晰。 –

3

改进凯泽的回答是:

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

不要忘记注入$document到你的指令

+19

正如在[element.find](https://docs.angularjs.org/api/ng/function/angular.element)的角度文档中所述:'find() - 仅限于通过标记名称查找,它不会不在ID上工作。你还有一个额外的关闭''''。 – paaat

+1

最后真的不应该有一个额外的括号...... –

6

这个工作对我很好。

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

元素是不确定的? angular.element.find对我来说不是一个没有JQuery的函数。 – landed

+3

请不要这样做。使用其他示例之一。这根本不使用哈希表查找优化。 – MatBee

9

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

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

如果您不需要jQuery的样式元素包裹,$文件[0] .querySelector( '#身份识别码')会给你的DOM对象。

+1

您可以直接引用window.document,而不是使用Angulars $文档服务开销。 – MatBee

+5

当然,如果你不担心在单元测试中嘲笑$文档 – Adamy

+0

对我来说不是很清楚:我得到这个warnig:你应该使用$ document服务而不是默认文档对象,但是这意味着什么?有关它的任何文档?谢谢! – realnot

3

也许我太晚了这里,但这种将工作:

var target = angular.element(appBusyIndicator); 

通知,也没有appBusyIndicator后,很纯的ID值。

什么幕后发生的事情:(假设它是应用在一个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); 
    } 

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

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

等于

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

可以访问使用$文件($文件需要被注入)元素

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

或具有角元素,指定的元素可被访问为:

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'); 
+1

find() - 仅限于通过标记名称查找 – RJV

+0

angular.element(document).find('。someClass');工作非常好。 –

7

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

使用 -

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