我已经构建了一个Angular指令来显示D3可视化。我在y轴上的$filter
函数中使用了tickFormat
,如下所示:
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
过滤器调用服务(异步操作),因为有几十种货币循环进出系统,详细信息我从数据库中检索。我确定这是我的tick标签未定义的原因。我该怎么做才能确保在页面加载后立即显示这些值?注意:我在调用tickFormat
时尝试将scope.$apply
功能打包,但我收到digest already in progress
错误。
答案 0 :(得分:8)
Axis的tickFormat方法运行传递的回调并使用它以同步方式返回的值。这就是为什么你在第一次通话时得到 undefined ,因为你的 $ filter 是异步的。
如果此异步调用仅出于性能原因,则应使其同步并在其他位置寻找改进。如果有角度观察这么多独立的变化,它可能会因$ digest周期而受阻。
如果你制作JSBin,我可能会告诉你更多。
答案 1 :(得分:1)
尝试使用Angular $timeout函数。
根据您的问题,问题可能是任何问题,但这就是我认为的问题:
它认为问题的一部分是你所得到的东西发生在事件循环的一个奇怪的位置。
$timeout是有用的函数,因为它在清除当前堆栈时运行,并且在经过n毫秒后运行,如果没有给出延迟时间,$ timeout只在堆栈展开后立即运行。它是在单个线程中执行异步代码的有用技巧。
使用$timeout 0延迟并不意味着回叫将在零毫秒后触发。我只是在处理完任务队列后执行。这是您想要更新标签的时间。
$timeout实际上会在准备好的情况下触发摘要。
$timeout(function() {
// Update the label with what comes back from the server
}, 0, false);
这是一个很好的视频,解释了Javascript事件循环的工作原理:What the heck is the event loop anyway?