角度嵌套指令数据绑定

时间:2015-07-30 18:31:29

标签: javascript angularjs nvd3.js

我在项目中使用this FAQ。它公开了一个看起来像这样的元素指令:

<div nvd3 options="" data=""></div>

这将根据选项和数据值呈现图表。它具有optionsdata属性的双向数据绑定。更改数据或选项时,图表会更新。

我一直在尝试将此指令包装在我自己的指令中,以使用不同的接口公开更少的功能(跟随angular-nvd3

ngModule.directive('myDirective', [function() {
  template: '<div nvd3 options="ctrl.options" data="ctrl.data"></div>',
  scope: {},
  bindToController: {
    w: '=',
    h: '='
  },
  controllerAs: 'ctrl',
  controller: ['$scope', function($scope) {
    var ctrl = this;
    $scope.$watch(function() { return ctrl.w; }, render );
    $scope.$watch(function() { return ctrl.h; }, render );

    function render() {
      ctrl.data = ctrl.data || {}       # omitted object definition
      ctrl.options = ctrl.options || {} # omitted object definition
      ctrl.options.chart.width = ctrl.w;
      ctrl.options.chart.height = ctrl.h;
    }

  }]
}]);

这适用于初始渲染。但是,在测试时,我在修改wh参数时似乎无法更新图表。

describe('my-directive', function() {

  var scope, element, render;

  function getSvgAttr(el, attr) {
    return el.find('svg')[0].getAttribute(attr);
  }

  beforeEach(inject(function($rootScope, $compile) {
    scope = $rootScope.$new();
    var compileFn = $compile(
      '<div my-directive w="w" h="h">'
    );
    render = function() {
      element = compileFn(scope);
       $rootScope.$digest();
    }
  }));

  it('should resize', function() {
    scope.w = 400;
    scope.h = 200;
    render();

    var ctrl = element.isolateScope().ctrl();

    expect(ctrl.w).toBe(400);
    expect(ctrl.h).toBe(200);

    expect(getSvgAttr(element, 'width')).toBe('400');
    expect(getSvgAttr(element, 'height')).toBe('200');

    scope.w = 200;
    scope.h = 400;
    scope.$digest();

    expect(ctrl.w).toBe(200);
    expect(ctrl.h).toBe(400);

    expect(ctrl.w).toBe(200);
    expect(ctrl.h).toBe(400);

    expect(getSvgAttr(element, 'width')).toBe('200');
    expect(getSvgAttr(element, 'height')).toBe('400');

  });

});

这是最后两个失败的断言。使用angular-nvd3,修改选项和数据会修改图形。

但是,当我添加一个包装器指令时,范围似乎会改变,但图形不会。

任何帮助将不胜感激!我的印象是bindToController我不需要任何$scope.$watch行。

1 个答案:

答案 0 :(得分:0)

似乎在上面的控制器中,您重复以下代码行:

$scope.$watch(function() { return ctrl.w; }, render );

我认为您打算将第二次迭代更改为以下内容:

$scope.$watch(function() { return ctrl.h; }, render );

因此,程序在双重观察“w”参数时绊倒,并且没有注意到'h'参数的更改。

然而,这可能只是问题的一部分。

希望它有所帮助,