在范围内更新ng-repeat循环数组后,视图未更新

时间:2014-06-21 10:06:27

标签: javascript angularjs angularjs-scope angularjs-ng-repeat

我正在尝试分别在数组'headers'和'records'中创建一个包含列名和记录的表。

<table class="table table-striped" id="dataset">
       <thead>
            <tr>
                <th>#</th>
                <th ng-repeat="header in headers">{{ header }}</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="record in records.slice(1,11)">
                <td>{{$index + 1}}</td>
                <td ng-repeat="cell in record">{{cell}}</td>
            </tr>
        </tbody>
 </table>

两个记录在开头都声明为null,并在用户选择要读取的csv后更新。一旦数组具有值,在控制器内部,我正在做 -

$scope.headers = headers;
$scope.records = records;

但是视图中没有创建元素。在控制台&gt;元素,ng-repeat指令出现了注释。

<table class="table table-striped" id="dataset">
       <thead>
            <tr>
                <th>#</th>
                <!-- ngRepeat: header in headers -->
            </tr>
        </thead>
        <tbody>
            <!-- ngRepeat: record in records.slice(1,11) -->
        </tbody>
</table>

我做错了什么?

这是完整的脚本:

    var VizApp = angular.module('VizApp', []);

    VizApp.config(function($routeProvider){

        $routeProvider
            .when('/overview',{
                    controller : 'VizController',
                    templateUrl : 'views/overview.html'
            })
            .when('/options', {
                controller : 'VizController',
                templateUrl : 'views/options.html'
            })
            .when('/charts', {
                controller : 'VizController',
                templateUrl : 'views/charts.html'
            })
            .otherwise({redirectTo : '/overview'})
    });

    var controllers = {};
    controllers.VizController = function($scope){

        var headers = [];
        var records = [];

        var csvPath;
        var cgiPath = '/cgi-bin/cgiTest.py';

        $scope.getCsv = function(selection){
            //Triggered when the user choses a csv from a file input

            csvPath = 'csvs/' + selection[0].files[0].name;
            $.ajax({
                type: "GET",
                url: csvPath,
                dataType: "text",       
                success: function(data) {
                    processData(data);
                }
            });
        };

        function processData(allText) {

            var allTextLines = allText.split(/\r\n|\n/);
            headers = allTextLines[0].split(',');  

            $.each(allTextLines.slice(1,allTextLines.length), function(i,thisRecord){
                records[i] = thisRecord.split(',');
            });

            console.log("Comes here");
            $scope.headers = headers;
            $scope.records = records; 
            //If I do a $scope.headers = ['a','b'] here, I still don't see two columns made with headers a and b

        }
        //If I do a $scope.headers = ['a','b'] here, I see two columns made with headers a and b
    };

    VizApp.controller(controllers);

</script>

感谢。

1 个答案:

答案 0 :(得分:1)

您需要在$scope.$apply()中包装更新范围的代码,如下所示:

$scope.$apply(function(){
       $scope.headers = headers;
       $scope.records = records; 
});

你需要这样做,因为你在异步回调中更新范围,该回调在不同的javascript中运行,关于哪个angularjs不知道。查看this post了解详情。

另一种方法是使用angularjs $http服务。在这种情况下,您不需要在$scope.$apply中包含范围更新,因为angularjs会为您执行此操作。

controllers.VizController = function($scope, $http){

        var headers = [];
        var varType = [];
        var records = [];
        var parameters = { 'xAxisVar' : '', 'yAxisVar' : '', 'sliceByVar' : '',    'chartByVar' : '', 'groups' : '', 'slices' : ''};

        var csvPath;
        var cgiPath = '/cgi-bin/cgiTest.py';


        $scope.getCsv = function(selection){
            //Triggered when the user choses a csv from a file input

            csvPath = 'csvs/' + selection[0].files[0].name;
            $http({method: 'GET', url: csvPath}).
            success(function(data, status, headers, config) {
                 processData(data);
            }).
            error(function(data, status, headers, config) {
            });
        };

        function processData(allText) {

            var allTextLines = allText.split(/\r\n|\n/);
            headers = allTextLines[0].split(',');  

            $.each(allTextLines.slice(1,allTextLines.length), function(i,thisRecord){
                records[i] = thisRecord.split(',');
            });

            $scope.headers = headers;
            $scope.records = records; 


        }
    };