1

svg チャートが通常よりも小さく表示されることがあります。この問題は、画面をリロードすると解決されます。

//Values Graphic
$scope.$watch(vm.dataGraphic.watch, function () {
    var data = vm.dataGraphic.watch ? $scope.$eval(vm.dataGraphic.watch) : vm.dataGraphic;

    setTimeout(sleep,500); //patch to "solve" this issue

    function sleep(){
        vm.dataValues = getDataValues(data);
    }

});
function getDataValues(data) {
    vm.dataGraphic = data || dataGraphicTest;
    if (vm.dataGraphic.values.length == 0) {
        return [];
    } else {
        vm.dataKeyValues = transformForKeyValues(vm.dataGraphic.values, vm.dataGraphic.accumulated);

        vm.barValues = transformBarValues(vm.dataGraphic.values, vm.dataGraphic.limit);
        var lineValues = transformLineValues(vm.barValues, vm.dataGraphic.limit, vm.dataGraphic.accumulated, vm.dataGraphic.startMonthlyLimit);
        vm.maxY = calculateMaxY(vm.barValues, lineValues);

        return [
            {
            "key": vm.dataGraphic.labelX.name,
            "bar": true,
            "color": _graphicsColors.bar,
            "values": vm.barValues
            },
            {
            "key": _graphicsValorPorDefecto,
            "color": _graphicsColors.line,
            "values": lineValues
            }
        ];
    }
}

次の html タグを持つ SVG 要素が間違ったサイズで表示されます。

<g class="nvd3 nv-wrap nv-linePlusBar" transform="translate(35,10)">

この問題は常に発生するわけではありませんが、発生した場合は画面をリフレッシュするように調整されています。

このパッチは悪い考えだと思います。何が起こっているのかを理解したいと思います。

ありがとう

4

1 に答える 1

2

あなたの問題は最終的にあなたの時計に起因すると思います:

$scope.$watch(vm.dataGraphic.watch, function () {
    var data = vm.dataGraphic.watch ? $scope.$eval(vm.dataGraphic.watch) : vm.dataGraphic;

    setTimeout(sleep,500); //patch to "solve" this issue

    function sleep(){
        vm.dataValues = getDataValues(data);
    }

});

私が見る問題はsetTimeout、時計が起動してから0.5秒後にスリープ機能を呼び出すために使用していることです。今のところ、$digest が 500 ミリ秒でまだ実行されている場合、これは問題ありません。setTimeoutはバニラの JavaScript 関数であるため、呼び出しても、$digest が終了した後に変更があったことを angularjs に通知しません。Angular は、ajax、クリック、データ入力などの「ユーザー開始」イベントの後にのみ $digest をトリガーします (詳細はこちらを参照)。$digest が実行されている場合は、運が良く、angularjs がたまたまそれらの変更を確認できます。$scope.$applyを使用して、angular に変更を通知する必要があります。

$scope.$watch(vm.dataGraphic.watch, function () {
    var data = vm.dataGraphic.watch ? $scope.$eval(vm.dataGraphic.watch) : vm.dataGraphic;

    setTimeout(sleep,500); //patch to "solve" this issue

    function sleep(){
        vm.dataValues = getDataValues(data);
        $scope.$apply();
    }

});

使い方はたくさんあります$scope.$applyので、ぜひドキュメントをチェックしてみてください。また、「いつ $scope.$apply を使用するか」などで検索すると、賛成派と反対派がたくさん見つかります。これは別の $digest ループをトリガーします。これは、多くのバインドがある場合、または最後のダイジェスト ループの最後にいて適用すると最初からやり直す場合にコストがかかる可能性があります。

setTimeoutウォッチ機能内から使用してモデルを更新することは、実際には良い考えではないと思います。これが無いと成り立たないのですか?同じ方法で適用する必要がある他の非同期コードがある場合があります。$scope.$apply一般に、 Angular 以外の非同期コードにできるだけ近づけたいと考えています。

于 2015-02-27T12:30:35.530 に答える