Dygraphs не работает с ng-repeat

Я новичок в AngularJS и создаю панель инструментов с dygraphs.

Попытался поместить пример кода с веб-сайта dygraphs в ng-repeat-list, просто для проверки. Ожидается один и тот же образец графика для каждого x в y. К сожалению график не рисуется, только оси, консоль ошибок не показывает.

<li ng-repeat="x in y">
    <div id="graph">
        <script>
            new Dygraph(document.getElementById("graph"),
                   [ [1,10,100], [2,20,80], [3,50,60], [4,70,80] ],
                   { labels: [ "x", "A", "B" ] });
        </script>
    </div>
</li>

Если я удаляю ng-repeat, он работает (один график) — поэтому код dygraphs действителен. Конечно, нет смысла рисовать графики прямо в представлении, как я сделал здесь, но все же интересно, почему это не работает. Я упускаю здесь какой-то общий момент?


person user3255061    schedule 30.01.2014    source источник


Ответы (1)


Ваша проблема в том, что Angular будет повторять ваши <div id="graph"> n раз. Итак, теперь у вас есть n раз div с идентификатором «графа», которые являются братьями и сестрами. Поэтому, когда вы вызываете document.getElementById('graph'), это не очень хорошо работает.

Тем не менее, я не знаю, насколько хорошо работают теги script внутри ng-repeat, это кажется очень странным вариантом использования.

Правильный способ сделать это (как и со всеми операциями, связанными с DOM) — использовать директиву. Вот пример:

Javascript:

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

myApp.controller('MyCtrl', function($scope) {
    $scope.graphs = [
        {
            data: [ [1,10,100], [2,20,80], [3,50,60], [4,70,80] ],
            opts: { labels: [ "x", "A", "B" ] }

        },
        {
            data: [ [1,10,200], [2,20,42], [3,50,10], [4,70,30] ],
            opts: { labels: [ "label1", "C", "D" ] }

        }
    ];
});

myApp.directive('graph', function() {
    return {
        restrict: 'E', // Use as element
        scope: { // Isolate scope
            data: '=', // Two-way bind data to local scope
            opts: '=?' // '?' means optional
        },
        template: "<div></div>", // We need a div to attach graph to
        link: function(scope, elem, attrs) {

            var graph = new Dygraph(elem.children()[0], scope.data, scope.opts );
        }
    };
});

HTML:

<div ng-controller="MyCtrl">
    <graph ng-repeat="graph in graphs" data="graph.data" opts="graph.opts"></graph>
</div>

JSFiddle

Надеюсь это поможет!

person SveinT    schedule 30.01.2014
comment
Большое спасибо, это сделало директивы намного яснее для меня и сделало работу! - person user3255061; 01.02.2014
comment
Хороший ответ, я обнаружил небольшую проблему при работе с этим: я не вижу способа указать div, который будет использоваться для меток. Любая идея о том, как добавить его? Поскольку labelsDiv необходимо указывать в данных с использованием идентификатора, я не могу найти способ обойти это :( - person Marcus Gabilheri; 17.05.2015
comment
Я предполагаю, что вы имеете в виду labelsDiv. Согласно документам, вы также можете передать элемент. Таким образом, вы добавляете новый div, в котором вы хотите, чтобы метки отображались в шаблоне директивы. Таким образом, у вас будет два родственных элемента div: один для самого графика и один для меток. Затем вы извлекаете оба элемента и вставляете ссылку на элемент метки в данные, которые вы предоставляете dygraph, и элемент графика, который вы предоставляете конструктору dygraph, как и раньше. Дайте мне знать, если это имеет смысл. - person SveinT; 26.05.2015
comment
@SveinT. спасибо, что поделились за ваш ответ. Мой вопрос связан с этим stackoverflow.com/ вопросы/43521905/ - person Varun Sharma; 24.04.2017