2016-03-30 2 views
1

У меня есть директива диаграммы в моем угловом приложении, которая использует библиотеку d3.js.d3.js - тест жасмина, чтобы вызвать щелчок на элементе svg

Часть директивы добавляет обработчик событий мыши для некоторых элементов SVG как так

svg.selectAll('g rect') 
    .on('click', function(d) { 
     scope.clickHandler(d, scope.data); 
    }) 
    .on('mouseover', function() { 
     d3.select(this).classed('data-item-hover', true); 
    }) 
    .on('mouseout', function() { 
     d3.select(this).classed('data-item-hover', false); 
    }); 

Я хочу, чтобы покрыть эти обработчик в некоторых модульных тестах, но борюсь с тем, как на самом деле вызывать эти события динамически.

Я пытаюсь это в моей тестовой спецификации

describe('scope.clickHandler', function() { 
    var rect; 
    beforeEach(function(){ 
     spyOn(scope, 'clickHandler'); 
     rect = svg.select('g rect')[0][0]; 
     rect.on('click')(); 
    }); 
    it('should call scope.render after a window resize event occurs', function() { 
     expect(scope.clickHandler).toHaveBeenCalled(); 
    }); 
}); 

Однако это выдает ошибку

TypeError: undefined is not a constructor (evaluating 'rect.on('click')'

Я наткнулся на это SO How to invoke "click" event programmatically in d3? и второй ответом является то, что привело меня к попытке этой техники ,

Как я могу вызвать событие мыши на элементах svg, которые у меня зарегистрированы в d3.js?

Благодаря

+0

См. Http://stackoverflow.com/questions/9063383/how-to-invoke-click-event-programmatically-in-d3 – jarandaf

+0

Это точная ссылка, на которую я ссылался в нижней части моего вопроса – mindparse

+0

My bad :) Я могу видеть только тонкую разницу: 'svg.select ('g rect') [0] [0]' является элементом DOM, а d3 связывает методы с самим массивом выбора, следовательно, ошибка – jarandaf

ответ

2

Основная проблема заключается в том, что svg.select('g rect')[0][0] является DOM элемент, а не правильный выбор D3, поэтому вы получите undefined ошибку. Из документов:

Selections are arrays of elements—literally (maybe not literally...). D3 binds additional methods to the array so that you can apply operators to the selected elements...

Вы можете реально проверить, так как DOM элемент реализует интерфейс Element:

(svg.select('g rect')[0][0] instanceof Element) // true 

Так что для того, чтобы вызвать какое-либо событие на определенный элемент, вы можете сделать следующее:

var rect = svg.select('g rect') // first rect element found is assumed 
rect.on('click').call(rect.node(), rect.datum()); // as commented in above link 

Вы можете найти простую рабочую скрипку here.

+0

Отличный ответ, спасибо! – mindparse

+0

Рад, что это сработало :) – jarandaf

Смежные вопросы