观看父对象时无限循环,观察者不更新任何值

时间:2016-03-23 19:41:48

标签: javascript angularjs

我有一个生成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对象的任何属性的更改,而不仅仅是数据,如上例所示。

1 个答案:

答案 0 :(得分:0)

我能够确定问题是由这一行引起的:

scope.elementObject.chartOptions.bindto = el;

link函数中的element object参数是被操作的DOM元素的jquery包装器。专门放置一个观察者,导致无限循环。

因为我在options对象中包含bindto属性,所以整个对象在观看时返回无限循环。

关于bindto的C3js文档:

  

如果未指定此选项,将生成图表但不会设置。相反,我们可以通过chart.element访问元素并自己设置

因此,解决方案是不在选项对象中包含bindto属性,然后通过chart.element访问它将生成的svg添加到指令中,例如:

function link(scope, elem) {

    ...

    var chart = c3.generate(scope.elementObject.chartOptions);
    elem.html(chart.element)
}