представление не обновляется после обновления массива циклов ng-repeat в области видимости

#javascript #angularjs #angularjs-scope #angularjs-ng-repeat

#javascript #angularjs #angularjs-область #angularjs-ng-repeat

Вопрос:

Я пытаюсь создать таблицу с именами моих столбцов и записями в массивах «заголовки» и «записи» соответственно.

 <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>
 

Обе записи объявляются нулевыми в начале и обновляются после того, как пользователь выбирает csv для чтения. Как только массивы имеют значения внутри контроллера, я делаю —

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

Но элементы не создаются в представлении. В консоли> элементы директива 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(/rn|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. Пожалуйста, дайте вашим сценариям два

2. Добавлен полный скрипт!

3. попробуйте изменить $scope.headers = [] на $scope.allheaders = {}; а затем => $scope.allheaders.headers = []; Я имею в виду поместить ваш массив внутри объекта

4. Не сработало. Хотя спасибо. Это решается с помощью приведенного ниже ответа.

Ответ №1:

Вам нужно обернуть свой код, который обновляет область $scope.$apply() , следующим образом:

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

Вам нужно это сделать, потому что вы обновляете область в асинхронном обратном вызове, который выполняется в другом повороте javascript, о котором angularjs не знает. Проверьте это сообщение для получения дополнительной информации.

Другой способ — использовать $http службу angularjs. В этом случае вам не нужно будет переносить обновление области $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(/rn|n/);
            headers = allTextLines[0].split(',');  

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

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


        }
    };