Использование $filter в директиве Angular
Я разработал директиву Angular для отображения визуализации D3. Я использую $filter
в функции tickFormat
на моей оси y так:
ySalesAxis = d3.svg.axis()
.orient('left')
.ticks(6)
.scale(ySalesScale)
.tickFormat(function(d) {
return $filter('formatSalesValue')(d.value, 'USD');
});
Проблема, которую я вижу, заключается в том, что ни одна из этих меток не появляется, когда страница загружается первой. Действительно, если я console.log($filter('formatSalesValue')(d.value, 'USD'))
, я получаю 6 undefined
(так как для свойства ticks
установлено значение 6). Однако, как только я предпринимаю действие, щелкнув внутри фильтра кисти, например, метки ярлыков отображаются правильно отформатированными.
![введите описание изображения здесь]()
Мой фильтр formatSalesValue
вызывает службу (асинхронная операция), потому что в систему и из нее задействованы десятки валют, подробности о которых я извлекаю из БД. Я уверен, что по этой причине мои метки ярлыков undefined. Что я могу сделать, чтобы убедиться, что эти значения отображаются сразу после загрузки страницы? Примечание. Я попытался обернуть мою функцию tickFormat
при вызове scope.$apply
, но я получаю ошибку digest already in progress
.
Ответы
Ответ 1
Метод Axis tickFormat запускает обратный вызов и использует значение, возвращаемое им синхронно. Вот почему вы получаете undefined при первом вызове, так как ваш $фильтр является асинхронным.
Если этот асинхронный вызов используется только по соображениям производительности, вы должны синхронизировать его и искать улучшения в другом месте. Если angular наблюдает за столькими независимыми изменениями, он может забиваться циклами $digest.
Если вы сделаете JSBin, я, вероятно, расскажу вам больше.
Ответ 2
TL; DR
Попробуйте использовать функцию Angular $timeout.
Исходя из вашего вопроса, проблема может быть любым количеством вещей, но это то, что я считаю проблемой:
Возможная проблема
Он считает, что часть проблемы заключается в том, что то, что вы получаете, происходит в странном бите цикла события.
$timeout - это полезные функции, поскольку он выполняется, когда текущий стек очищается и после прохода n миллисекунд, если нет времени на задержку данный, $timeout просто запускается, как только пакет распаковывается. Это полезный трюк для выполнения асинхронного кода в одном потоке.
Использование $timeout с задержкой 0 на самом деле не означает, что обратный вызов будет погашен после нулевого миллисекунды. Я просто запускаю выполнение после обработки очереди задач. Это когда вы хотите обновить свои метки.
$timeout фактически вызовет дайджест, когда он будет готов к этому.
Возможное решение
$timeout(function() {
// Update the label with what comes back from the server
}, 0, false);
Это хорошее видео, объясняющее, как работает цикл событий Javascript: Какая черта в цикле событий?