Я использую angular-nvd3 в проекте. Он предоставляет директиву элементов, которая выглядит так:
<div nvd3 options="" data=""></div>
Это отображает диаграмму в соответствии с параметрами и значениями данных. Он имеет двустороннюю привязку данных для атрибутов options
и data
. Когда вы меняете данные или параметры, диаграмма обновляется.
Я пытаюсь включить эту директиву в свою собственную директиву, чтобы показать меньшую функциональность с помощью другого интерфейса (следуя по https://www.airpair.com/angularjs/posts/component-based-angularjs-directives)
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;
}
}]
}]);
Это отлично подходит для первоначального рендеринга. Однако при тестировании я не могу заставить диаграмму обновляться при изменении параметров w
или h
.
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
.
Похоже, что в вашем контроллере выше вы повторяете следующую строку кода:
$scope.$watch(function() { return ctrl.w; }, render );
Я предполагаю, что вы хотели изменить вторую итерацию на следующее:
$scope.$watch(function() { return ctrl.h; }, render );
В результате программа отключается при двойном просмотре параметра "w" и не следит за изменениями параметра "h".
Однако это может быть только частью проблемы.
Надеюсь, поможет,
C§