У меня есть директива, которая генерирует диаграмму C3js. У меня есть объект, который содержит различные свойства C3. Если входящий элемент уже имеет объект chartOptions
, он используется, но если нет, то объект по умолчанию добавляется.
scope.elementObject.chartOptions = scope.elementObject.chartOptions || chartOptions;
Я пытаюсь следить за любыми изменениями в объекте chartOptions
потому что он будет взаимодействовать с внешней директивой, однако простое создание наблюдателя без добавления какой-либо функции вызывает бесконечный цикл. Ни один из регулярных решений бесконечного цикла не работает, потому что я не изменяю объект внутри наблюдателя.
scope.$watch('elementObject.chartOptions', function () {
console.log('changed')
}, true);
//INFINITE LOOP
Если, однако, я смотрю дочерний объект, то я не получаю бесконечный цикл, например
scope.$watch('elementObject.chartOptions.data', function () {
console.log('changed')
}, true);
//NO INFINITE LOOP
директива
app.directive('newchart', function () {
return {
scope: {
data: "=",
elementObject: "=element"
},
restrict: 'E',
link: link
};
function link(scope, elem) {
var el = elem[0];
var chartOptions = {
data: {
columns: [['data1', 30, 200, 100, 400, 150, 250]],
type: 'spline',
labels: false
},
interaction: { enabled: true },
grid: { x: { show: false }, y: { show: false } },
legend: { show: true, position: 'bottom' },
tooltip: { show: true, grouped: true }
};
scope.elementObject.chartOptions = scope.elementObject.chartOptions || chartOptions;
scope.elementObject.chartOptions.bindto = el;
var chart = c3.generate(scope.elementObject.chartOptions);
scope.$watch('elementObject.chartOptions', function () {
console.log('changed')
}, true);
};
});
Мне нужно иметь возможность следить за изменениями любого из свойств объекта chartOptions
, а не только данных, как это было в примере выше.
Я смог определить, что проблема была вызвана этой строкой:
scope.elementObject.chartOptions.bindto = el;
element
объект аргумент в функции связи является JQuery оболочка элемента DOM манипулирует. Помещение наблюдателя на это специально вызвало бесконечный цикл.
Поскольку я bindto
свойство bindto
в объект options, весь объект затем возвращал бесконечный цикл при просмотре.
Из документации bindto
о bindto
:
Если этот параметр не указан, диаграмма будет сгенерирована, но не будет установлена. Вместо этого мы можем получить доступ к элементу chart.element и установить его сами
Таким образом, решение состоит в том, чтобы не включать свойство bindto
в объект опций, а затем добавить сгенерированный svg в директиву, chart.element
к нему через chart.element
, например:
function link(scope, elem) {
...
var chart = c3.generate(scope.elementObject.chartOptions);
elem.html(chart.element)
}