javascript - 在范围内更新 ng-repeat 循环数组后 View 未更新

标签 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 后更新。一旦数组具有值,在 Controller 内,我正在做 -

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

但是元素不是在 View 中创建的。在 console > elements 中,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>

谢谢。

最佳答案

您需要将更新范围的代码包装在 $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; 


        }
    };

关于javascript - 在范围内更新 ng-repeat 循环数组后 View 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24340515/

相关文章:

javascript - 可调整大小的侧边栏 - 拖动即可调整大小

javascript - 手动钻取 Highcharts

php - 谷歌地图不显示

javascript - 我应该如何在 Angular ui-router 中创建 templateUrl 属性的路径?

angularjs - 筛选数字范围 : AngularJS

javascript - 逻辑关键字 || 是否只获取值 true 或 false?

javascript - 将新项目推送到 mongoDB 文档数组

php - Angularjs $http.post,将数组传递给 PHP

javascript - 在 AngularJS 中输入返回数字而不是字符串

javascript - 如何从指令的 Controller 调用依赖注入(inject)服务的嵌套方法?