【问题标题】:javascript iterate over array of objectsjavascript遍历对象数组
【发布时间】:2017-05-31 19:37:27
【问题描述】:

我在一个 Angular 应用程序中工作,并且在一个控制器内部我需要迭代一个对象数组。这是这种情况下涉及的控制器和代码:

myapp.controller('LoginController', ['$scope',  function(scope) {
    // Users for test
    this.users = [
        {
            name: 'admin',
            password: 'admin',
            role: 'ADMIN'
        },
        {
            name: 'employee',
            password: '12345',
            role: 'EMPLOYEE'
        }
    ];
    console.dir(this.users); // Prints an array of objects correctly

    // called when user submits
    scope.login = function() {
        console.log('login(). User: ');
        console.dir(scope.user); // Prints the object with user's input (also correct)

        var found = false;

        for(let u of this.users) {
            console.log('Comparing with:');
            console.dir(u);

            if(u.name == scope.user.name && u.password == scope.user.password) {
                console.log('Found!');
                found = true;

                // do something else...
            }
        }

        if(!found) { // show error message... }
    }
}]);

问题是当我提交登录表单(调用scope.login())时,我在控制台中收到一条错误消息:

TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
    at m.scope.login (loginController.js:44)
    ...

loginController.js:44 对应于for(let u of this.users) { 行。我在网上搜索(W3 Schools、MDN 和这个网站),但解决方案对我不起作用。我已经尝试了以下解决方案:

  • for(var u of this.users)
  • var u; for(u in this.users)
  • for(var i = 0; i < this.users.lenght; i++):这会将错误消息更改为Cannot read property 'length' of undefined

我觉得这很简单,但我不知道它是什么(我对 Javascript 不是很熟练,抱歉)。谁能帮我解决这个问题?

提前感谢您的回答。

【问题讨论】:

  • this.users 未定义吗?
  • 你为什么使用this?您应该不使用scope 还是只使用普通的varlet?因为当你到达函数时,this 指的是函数
  • @Chifilly 这是controller as 语法。首选$scope

标签: javascript angularjs loops


【解决方案1】:

登录函数中的范围正在改变,因此变量this 与之前在该函数中的不同。

scope.login = function() {之前可以写:

var _this = this;

然后使用_this.users.forEach(function(user) {

for (var i = 0; i < _this.users.length; i++)

【讨论】:

  • 我会认为你的回答是正确的,我使用了var users = [...],所以我可以在整个控制器中使用它并且完美地工作。非常感谢
【解决方案2】:

this 上下文在您的scope.login = function () {} 中发生变化,因为它是一个对象方法,this 是对scope 的引用。试试这个:

myapp.controller('LoginController', ['$scope',  function(scope) {
    var that = this; // reference to the correct this context
    // Users for test
    this.users = [
        {
            name: 'admin',
            password: 'admin',
            role: 'ADMIN'
        },
        {
            name: 'employee',
            password: '12345',
            role: 'EMPLOYEE'
        }
    ];
    console.dir(this.users); // Prints an array of objects correctly

    // called when user submits
    scope.login = function() {
        console.log('login(). User: ');
        console.dir(scope.user); // Prints the object with user's input (also correct)

        var found = false;
        for(let u of that.users) { // use the correct context here
            console.log('Comparing with:');
            console.dir(u);

            if(u.name == scope.user.name && u.password == scope.user.password) {
                console.log('Found!');
                found = true;

                // do something else...
            }
        }

        if(!found) { // show error message... }
    }
}]);

【讨论】:

  • 您也可以将this.users 更改为scope.users,一切都会按预期进行。
  • 值得注意的是that != $scope,差异在控制器中不会立即明显,但会在HTML上,同样使用this而不是$scope是相当基于意见的,我相信使用this 的一个原因是在使用Controller as 语法在HTML 中引用它时强制使用点表示法(因为不使用点表示法可以并且将最终给出意外错误)跨度>
  • this 在对象的方法内引用父对象。在这种情况下,this$scope 对象上的方法内引用 $scopethis 并不总是 $scope 是正确的,但在这种情况下它是。
  • 它实际上并没有,正如你所看到的in this article,angularjs 的作用域不是使用this 检索的javascript 引用,而是它们是由angularjs 处理的用于封装的集合数据(其中this 是子作用域,$scope 是父作用域)...您可以通过使用浏览器中的调试器在this 上设置断点来验证这一点,看看它的计算结果是什么,然后看看什么$scope 评估为;你会发现$scope.ctrl是控制器顶层this所指的
  • 注意:当我说 $scope.ctrl 时,ctrl 指的是控制器的名称,然后是 Controller as ctrl 语法,当不使用该语法时 this 在 @ 中找不到987654351@(也找不到它的属性)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-18
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
相关资源
最近更新 更多