"ui-view"内部"ng-repeat"会导致"TypeError: Cannot read property 'insertBefore' of null"异常 [AngularJS]



当用户进入父级的一个子状态时,我试图更改父级视图的一部分。

下面是一个简短的代码片段,用来演示我的意图和由此产生的异常。

<!doctype html>
<html data-ng-app="myModule">
<body>
    <div data-ui-view>
        Type Info: {{ typeInfo }}
        <div data-ui-view>
            <button data-ng-repeat="type in tArray" data-ng-click="changeT(type)">
                {{ type.desc }}
            </button>
        </div>
    </div>
    <script src="./angular.min.js"></script>
    <script src="./angular-ui-router.js"></script>
    <script>
        var module = angular.module('myModule', ['ui.router']);
        module.controller('MyCtrl', function($scope, $state) {
            function testType(description, color) {
                this.desc = description;
                this.color = color;
            }
            $scope.tArray = [
                new testType('First', 'red'),
                new testType('2nd', 'blue'),
                new testType('Third (3rd)', 'green')
            ];
            $scope.typeInfo = {};
            $scope.changeT = function(typeObj) {
                $scope.typeInfo.t = typeObj;
                $state.go('.childState');
            };
        });
        module.config(function($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.when("", "/");
            $stateProvider
                .state('root', {
                    url: '/',
                    controller: 'MyCtrl'
                })
                .state('root.childState', {
                    url: '/child',
                    template: 'I am the child!<button ui-sref="root">root</button>'
                });
        });
    </script>
</body>
</html>

这似乎与"ui视图"中的"ng repeat"有关。如果删除"ng repeat",则不会出现异常。有趣的是,如果我注释掉"$scope.tArray"的声明,那么也不会发生异常。

代码的JSFiddle:

http://jsfiddle.net/cdvhmxp0/4/

使用Chrome可以看到异常。在Firefox中,它似乎抛出了一个"错误:parentNode为null"异常。然而,在功能上,代码似乎按预期工作。

TypeError:无法读取null 的属性"insertBefore"

我对AngularJS还比较陌生,所以如果我以一种做作、不习惯或不合逻辑的方式做事,请随时告诉我。

谢谢你的帮助。

这里的主要问题是,现在您试图为子ui视图定义两次模板。第一次在config中,第二次在html中。您可以定义其中两个子状态来实现默认视图,而不是定义一个子状态,并将根状态设置为没有url的抽象状态。我已经修改了你的代码,现在没有错误:

<div data-ng-app="myModule">
    <div data-ui-view>
        Type Info: {{ typeInfo }}
        <div data-ui-view></div>
    </div>
    <script>
        var module = angular.module('myModule', ['ui.router']);
        module.controller('MyCtrl', function($scope, $state) {
            function testType(description, color) {
                this.desc = description;
                this.color = color;
            }
            $scope.tArray = [
                new testType('First', 'red'),
                new testType('2nd', 'blue'),
                new testType('Third (3rd)', 'green')
            ];
            $scope.typeInfo = {};
            $scope.changeT = function(typeObj) {
                $scope.typeInfo.t = typeObj;
                $state.go('root.childState');
            };
        });
        module.config(function($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise("/");
            $stateProvider
                .state('root', {
                    controller: 'MyCtrl',
                    abstract: true
                })
                .state('root.default', {
                    url: '/',
                    template: '<button data-ng-repeat="type in tArray" data-ng-click="changeT(type)">{{ type.desc }}</button>'
                })
                .state('root.childState', {
                    url: '/child',
                    template: 'I am the child!<button ui-sref="root.default">root</button>'
                });
        });
    </script>
</div>