【问题标题】:get html elements in angularJS在angularJS中获取html元素
【发布时间】:2017-01-26 08:19:10
【问题描述】:

我是 AngularJS 世界的新手。我这里有个情况。

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp">

<table ng-controller="myCtrl" border="1">
<tr class="x" ng-repeat="x in records">
  <td>{{x.Name}}</td>
  <td>{{x.Country}}</td>
</tr>
</table>

<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
  $scope.records = [
    {
      "Name" : "Alfreds Futterkiste",
      "Country" : "Germany"
    },
    {
      "Name" : "Berglunds snabbköp",
      "Country" : "Sweden"
    },
    {
      "Name" : "Centro comercial Moctezuma",
      "Country" : "Mexico"
    },
    {
      "Name" : "Ernst Handel",
      "Country" : "Austria"
    }
  ];
  var arrays = document.getElementsByClassName("x");
  console.log(arrays.length);
});
</script>

我试图获取我通过 angularJS 加载的 html 元素数组(使用 ng-repeat)。当我记录整个数组的值时,它的结果是正确的。但是,当我记录 array.length 或 array[1] 时,结果分别为 0 和未定义。我尝试将这些代码放入 $scope.on('viewContentLoaded') 以确保所有 html 元素都完成加载,但结果是相同的。那么我在这里的愚蠢是什么?

谢谢。

**** 解决方案:

 $timeout(function(){
 var arrays = document.getElementsByClassName("x");
 console.log(arrays.length);
 });

感谢@Vladimir M

【问题讨论】:

  • 你为什么不直接通过角度获取数组:$scope.records? $scope.records.length?
  • 我只是想获取 html 元素来操作它们; array.length 不是我的目的;我只是用它来测试。 :)

标签: javascript angularjs javascript-objects


【解决方案1】:

要记住的一件事是,Angular 正在异步执行某些操作。当您在控制器中分配记录时,角度只会在您的控制器方法完成后开始渲染。因此,您对文档元素的请求将不会返回任何内容。

在某些情况下绕过它的一种方法是使用 $timeout 服务。

$timeout(function(){
 var arrays = document.getElementsByClassName("x");
  console.log(arrays.length);
});

应该在角度摘要循环完成渲染时执行超时内的方法。

【讨论】:

  • 它对我有用。但我想深入挖掘以了解更多。据我所知,$timeout 服务与 setTimeOut 函数类似,这意味着它允许我们在延迟时间之后执行函数。那么 Angular 如何知道所有视图都完成加载然后运行 ​​$timeout 服务?我想到了所有视图都还没有完成加载的情况,所以我尝试将这些代码放在 $scope.on("viewContentLoaded")、angular.element(document).ready 和 $(document).ready 中(jQuery) 以确保一切都完成加载,但它在这里不起作用。感谢您帮助我!
  • 它与角度内的摘要循环有关。您为其创建控制器的特定元素的渲染将在该控制器方法中创建的所有超时之前发生。但是,当模板包含一些其他元素和自己的控制器时,事情会变得更加复杂,因为这些元素很可能会在安排给定的超时时间后处理。
  • 哦,我明白了。非常感谢。
  • 你好。我有个问题。如果我只想通过AngularJs获取这些html元素(不使用javascript或jquery的任何选择器),那么有什么方法可以实现吗?谢谢你。 P/S:如果我太打扰你了,请忽略这个问题。我只是想了解更多关于 AngularJS 的信息。很抱歉。
  • 我没有做太多,因为原生或 jQuery API 对我来说已经足够了。您将能够从角度获得对当前范围元素的引用:link,但是,不适用于没有自己范围的元素。就个人而言,我认为没有充分的理由不使用 jQuery 或 document.getElement.... API。
【解决方案2】:

你需要把代码封装在里面

angular.element(document).ready(function(){});

喜欢这个

angular.element(document).ready(function(){
var arrays = document.getElementsByClassName("x");
console.log(arrays[2]);
});

你可以参考 Demo

我还尝试了记录整个数组或 array.length 的代码,但它不起作用。 实际上,在渲染 DOM 之前它不会起作用。 所以上面的代码会等到文档准备好,一旦文档被渲染,你就可以访问 html 元素了。

【讨论】:

  • hmm.. 它在 plnkr 上工作,但在我的本地和 w3school 试用中不起作用。超级奇怪。
  • 您可以尝试更改 angular.min.js 脚本参考。实际上我也在plnkr中更新了它。就我而言,它不适用于您在代码中的引用。
【解决方案3】:

Angular 是一个 MVC 框架。 MVC 代表“模型视图控制器”, 这意味着您的应用程序应分为 3 个部分:

  1. 视图(html 中的任何指令,例如 ng-repeat)。
  2. 控制器(您的 app.controller、控制范围和)
  3. 存储业务逻辑和功能的模型(角度、服务/工厂)。 例如,在您的情况下,角度工厂可能会返回一组用户(姓名、国家/地区),您的控制器会将其传递给 $scope,然后会自动将其传输到您的视图。

只是指出,按照惯例,这些(视图、控制器、模型)中的每一个都放在不同的文件中。

您可能已经知道,Angular 的另一个显着特性是双向绑定。 这意味着视图中的任何更改都会反映在模型和控制器中,反之亦然。 这对您来说意味着您的 ng-repeat 将始终准确地代表您在 $scope.records 中的内容。 只需控制台记录一下。

angular 有时会以神秘的方式工作,并不意味着您可以使用选择器。从来没有必要使用角度,这是角度的另一个优点。没有选择器!

【讨论】:

  • 是的,我知道这个理论,但我只是认为它与javascript和jQuery相似;当一切都加载完成后,我们可以操作 DOM。唔。我只是想了解更多关于角度的信息。谢谢你
  • @Justin 是的,您可以操作 DOM。 MVC 架构只是假设您不应该这样做。检查这个关于 AngularJS 哲学与 jQuery 哲学有何不同的好答案 - stackoverflow.com/a/15012542/3091161
【解决方案4】:

您正试图在渲染之前获取 li 元素。 S0 正如@DashingDev 所说,您需要将代码块移动到angular.element(document).ready(function(){});。你的代码应该看起来

angular.element(document).ready(function(){
  var multibutton = document.getElementsByClassName("x");
    console.log(multibutton[0]);
}); 

这里是Working fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    相关资源
    最近更新 更多