【问题标题】:Google Charts doesn't get updated when Firebase data has changed当 Firebase 数据发生变化时,Google 图表不会更新
【发布时间】:2016-06-26 19:02:16
【问题描述】:

我已经设法将我的 Firebase 连接到谷歌图表,效果很好,但我正在努力解决如果没有数据可以评估为简单的 if else 表达式我如何显示一条简单的消息“无数据”已经宣布了。

例如,我为单个用户设置了“NA”的 Firebase 数据值,这在理论上意味着默认情况下图表不会显示,并且错误消息会在页面加载时显示,并且在任何时候这变回这个值。但是,情况并非如此,触发它的唯一方法是单击我在 HTML 文件中设置的 3D 按钮。此外,当 Firebase 数据更改为大于零的值时,仍会显示错误消息。

这是我的代码:

JS 文件

var displayMode = true;

$scope.statistics = function () {
    $mdSidenav('left').close();
    $state.go('statistics');
    $timeout(function () {
        setUpChart();
        var timer;
        $(window).on('resize', function () {
            clearTimeout(timer);
            timer = setTimeout(function () {
                setUpChart();
            }, 250);
        });
    });
};

function setUpChart() {

    $.ajax({
        url: '//www.google.com/jsapi',
        dataType: 'script',
        cache: true,
        success: function () {
            google.load('visualization', '1', {
                'packages': ['corechart'],
                'callback': drawChart
            });
        }
    });

    function drawChart() {

        // This links to my Firebase url
        userRef.on('value', function (snapshot) {

            var pass = 0;
            var fail = 0;

            snapshot.forEach(function (snapshot) {
                var userResults = snapshot.val();
                if (userResults.passFail === 'Pass') {
                    pass = pass + 1;
                }
                if (userResults.passFail === 'Fail') {
                    fail = fail + 1;
                }
            });

            if (pass === 0 && fail === 0) {
                console.log('No data: ' + pass + ' & ' + fail);
                $scope.error = true;
                $scope.errorMessage = 'No user data available, please try  
                again later.';
            } else {
                console.log('Is data: ' + pass + ' & ' + fail);
                $scope.error = false;
                $scope.errorMessage = null;
                var data = new google.visualization.DataTable();
                data.addColumn('string', 'Result');
                data.addColumn('number', 'Delegates');
                data.addRows([
                    ['Pass', pass],
                    ['Fail', fail]
                ]);

                var options = {
                    'is3D': displayMode,
                    'chartArea': {'width': '100%', 'height': '80%'},
                    'legend': {'position': 'top', 'alignment': 'center'}
                };

                var chart = new 
         google.visualization.PieChart(document.getElementById('pieChart'));
                chart.draw(data, options);
            }

        });

    }

}

// Changes chart type to 3D or top view on a butto click
$scope.chartFormat = function () {
    if (displayMode == true)
        displayMode = false;
    else
        displayMode = true;
    setUpChart();
};

HTML

<div class="container" style="padding-top: 100px; padding-bottom: 50px">

<button data-ng-model="displayType" style="display: block; margin: 0 auto"
        data-ng-click="displayType=displayType ? false : true;  
        chartFormat()"
        class="btn btn-default btn-md" type="button"><i class="material-
        icons">3d_rotation</i></button>

<div data-ng-if="error" class="alert alert-danger">
   <span data-ng-if="errorMessage" class="glyphicon glyphicon-remove">  
   </span><strong> {{errorMessage}}</strong>
</div>

<div id="pieChart" style="display: block; margin: 0 
auto; width: 100%; height: 500px"></div>

</div>

【问题讨论】:

  • 请注意,更新范围的角度核心外部代码需要通知角度运行摘要。
  • 由于我以前没有使用过这种方法,请您举例说明一下吗?
  • 使用$scope.$apply()

标签: javascript jquery angularjs firebase google-visualization


【解决方案1】:

只要 Firebase 中的数据发生变化,您在 userRef.on('value', function (snapshot) { 中的代码就会异步运行。那时 AngularJS 并不期待 $scope 发生变化,所以它看不到它们。

解决方案是让 AngularJS 知道您更改了 $scope 的事实,方法是按照 charlieftl 的建议调用 $scope.$apply() 或将其包装在 $timeout() 中,以便在下一个摘要周期中获取它:

userRef.on('value', function (snapshot) {
    $timeout(function() {
        var pass = 0;
        var fail = 0;

        snapshot.forEach(function (snapshot) {
            var userResults = snapshot.val();
            if (userResults.passFail === 'Pass') {
                pass = pass + 1;
            }
            if (userResults.passFail === 'Fail') {
                fail = fail + 1;
            }
        });

        if (pass === 0 && fail === 0) {
            console.log('No data: ' + pass + ' & ' + fail);
            $scope.error = true;
            $scope.errorMessage = 'No user data available, please try  
            again later.';
        } else {
            console.log('Is data: ' + pass + ' & ' + fail);
            $scope.error = false;
            $scope.errorMessage = null;
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Result');
            data.addColumn('number', 'Delegates');
            data.addRows([
                ['Pass', pass],
                ['Fail', fail]
            ]);

            var options = {
                'is3D': displayMode,
                'chartArea': {'width': '100%', 'height': '80%'},
                'legend': {'position': 'top', 'alignment': 'center'}
            };

            var chart = new 
     google.visualization.PieChart(document.getElementById('pieChart'));
            chart.draw(data, options);
        }

    });

});

【讨论】:

  • 您好弗兰克,感谢您的回复。我之前确实尝试过这种方法,只是再次尝试看看它是否有效。但是,它会抛出一个错误为“错误:未定义容器”,以下代码引用 Pp@google.com/uds/api/visualization...
  • 忽略我过去的评论,我的 html 中有一个用于饼图的“data-ng-if”,现在我已将其删除。但是,它仍然无法通过显示错误消息来工作。这仅在第一页加载时出现,它应该显示消息。例如,如果我手动将 Firebase 数据值更改为“通过”,它将按照我的意愿开始工作
【解决方案2】:

如果有人遇到与上述类似的问题,只需将 data-ng-init="function_name_here()" 添加到您希望在您的 Google 图表中显示的错误消息 div 中没有数据。

以前从未想过这一点,但现在可以解决问题,并在我的案例中动态显示错误消息并在数据存在时删除该消息!

【讨论】:

    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 2017-11-25
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多