【问题标题】:AngularJS: Hitting a strange issue with $scope variablesAngularJS:使用 $scope 变量遇到一个奇怪的问题
【发布时间】:2012-07-31 21:22:15
【问题描述】:

在下面的代码中,每当你从列表中的删除链接中删除一个项目时,它只会从列表中删除该项目,但不会删除当前选中的项目。 (单击后显示的项目)。但是,如果您单击当前所选项目旁边的删除链接,它将从两个位置删除。

复制我所看到的:

  • 通过在文本框中键入并按几次 Enter 来添加一堆项目。
  • 从列表中选择一项。
  • 当项目显示在下方时,单击项目旁边的删除。
  • 这是正确的行为。
  • 选择您之前创建的另一个项目。
  • 现在单击列表中项目旁边的删除链接。
  • 项目已从列表中移除,但当前显示的项目并未移除。

当我进入代码时,当我单击列表中的删除链接时,$scope.currentUser 未定义。

为什么会这样?

<html ng-app="myApp">
<head>
    <script src="http://code.angularjs.org/1.0.1/angular-1.0.1.min.js"></script>
    <script>
    var app = angular.module('myApp', []);

    app.config(function($routeProvider) {
        $routeProvider.when('/User/:id', {
            controller: UserCtrl,
            template: '<h1>{{currentUser.name}}</h1> <a ng-click="deleteUser(currentUser.id)">delete me</a>'
        });
    });

    app.factory('userSvc', function(){ 
        return new UserService();
    });

    function UserCtrl($scope, $routeParams, $location, userSvc) {
        var currUser = userSvc.getUser($routeParams.id);
        $scope.currentUser = currUser;
        $scope.users = userSvc.getAllUsers();

        $scope.addUser = function () {
            var user = { 
                id: userSvc.nextId(),
                name: $scope.addUserName
            };
            userSvc.addUser(user);
            $scope.addUserName = '';
            $location.url('/User/' + user.id);
        };

        $scope.deleteUser = function(id) {      
            if($scope.currentUser != null && $scope.currentUser.id == id) {
                $scope.currentUser = null;
            }
            userSvc.delete(id);
        };
    };

    function UserService() {
        var users = [{id: 1, name: 'Ben' }];

        this.delete = function(id) {
            for(var i = 0; i < users.length; i++) {
                var user = users[i];
                if(user.id == id) {
                    users.splice(i,1);
                }
            }
        };

        this.addUser = function(user) {
            users.push(user);
        };

        this.getAllUsers = function() {
            return users;
        };

        this.getUser = function(id) {
            for(var i = 0; i < users.length; i++) {
                var user = users[i];
                if(user.id == id) {
                    return user;
                }
            }
        };

        this.nextId = function() {
            var maxId = 0;
            for(var i = 0; i < users.length; i++) {
                var user = users[i];
                maxId = Math.max(maxId, user.id);
            };
            return maxId + 1;
        };
    }
    </script>
</head>
<body>
<div ng-controller="UserCtrl">
    <form ng-submit="addUser()">
        <input ng-model="addUserName" type="text"/>
        <input type="submit" value="Add"/>
    </form>
    <ul>
        <li ng-repeat="user in users"><a href="#/User/{{user.id}}">{{user.name}}</a> <a ng-click="deleteUser(user.id)">delete</a></li>
    </ul>
</div>
<div ng-view></div>
</body>
</html>

【问题讨论】:

  • 看起来这可能与点击链接显示项目时模板中绑定的项目的实际范围不同有关。
  • 如果您还没有尝试过,请查看 AngularJS Batarang Chrome 扩展来解决范围问题:github.com/angular/angularjs-batarang
  • 太棒了,我还没有看到这个。
  • 使用 Batarang,我完全正确,定义了多个范围。

标签: javascript angularjs


【解决方案1】:

事实证明,从列表中选择用户实际上还创建了一个全新的范围,该范围与用于绑定列表的范围分开。

感谢 Gloopy 在上面查看 Batarang 的评论,我能够看到这种情况发生。如果这对您有帮助,请 +1 他的评论。

根据the documentation on Scopes,一些指令实际上会导致创建一个新的范围。我假设单击 $routeProvider 正在处理的链接也会导致创建一个全新的范围树,可能是因为它正在创建该控制器的另一个实例。

【讨论】:

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