我的基本问题是我在指令中有一个d3图表,我希望它在按下按钮提交时显示。指令中的d3代码包含在promise.then
中,因为它必须从$http.get(...)
请求中获取数据。
现在我的策略是:a-一个按钮,其ng-click
属性链接到我的控制器中的函数chnagePresent()
; b - 根据指令是否应显示图表,使变量$scope.present
取值true
或false
;指令内的c-a $watch
元素,绑定到控制器中的$scope.present
,并在回调函数中包含if
语句。如果$scope.present
等于true,则触发该指令,否则不执行任何操作(此处只有一条虚拟消息打印到控制台)。
代码如下所示:
指令:
.directive('ngGraphfingerprint',['getGraphsService',function(getGraphsService){
return{
restrict: 'A',
scope : {},
controller: 'MainCtrl',
link: function(scope,element,attrs){
var expression = scope.present
scope.$watch(expression,
function(newValue){
if (newValue === true){
// var dataset = [
// {'startYear' : '2005-01-12',
// 'label' : 'green',
// 'value' : 0.6,
// 'ceo' : 'Marcus Tetha'},
// {'startYear' : '2005-01-12',
// 'label' : 'green',
// 'value' : 0.6,
// 'ceo' : 'Marcus Bo'},
// {'startYear' : '2007-06-07',
// 'label' : 'red',
// 'value' : 0.9,
// 'ceo' : 'Marcus Alpha'},
// {'startYear' : '2011-03-04',
// 'label' : 'red',
// 'value' : 0.03,
// 'ceo' : 'Marcus Gamma'},
// {'startYear' : '2011-07-28',
// 'label' : 'yellow',
// 'value' : 0.1,
// 'ceo' : 'Marcus Beta'}
// ];
getGraphsService.FunctionF().prom.then(
var w = 750;
var h = 400;
var padding = 30;
var svg = d3.select(element[0])
.append('svg')
.attr('width',w)
.attr('height',h);
var xScale = d3.time.scale()
.domain([new Date('2004-01-01'),new Date('2014-12-31')])
.range([padding*2.5,w-padding*0.5]);
var yScale = d3.scale.ordinal()
.domain(dataset.map(function(d){return d.ceo;}))
.rangeBands([h - padding, padding]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient('left')
.ticks(4);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(d3.time.years)
.tickFormat(d3.time.format('%Y'));
var axisStyle = {'fill': 'none', 'stroke': 'black','shape-rendering': 'crispEdges','font-family':'sans-serif','font-size': '11px'};
svg.append('g')
.style(axisStyle)
.attr('transform', 'translate(0,' + (h - padding) + ')')
.attr('text-anchor', 'end')
.call(xAxis);
svg.append('g')
.style(axisStyle)
.attr('transform', 'translate(' + padding*2.5 + ',0)')
.attr('text-anchor', 'end')
.call(yAxis);
svg.selectAll('rect')
.data(dataset)
.enter()
.append('rect')
.attr('x',function(d){return xScale(new Date(d.startYear));})
.attr('y',function(d){return yScale(d.ceo)+yScale.rangeBand()/2-10;})
.attr('height',20)
.attr('width',20)
.attr('fill',function(d){return d.label;});
svg.selectAll('text.label')
.data(dataset)
.enter()
.append('text')
.attr('class','label')
.attr('x',function(d){return xScale(new Date(d.startYear)) + 10;})
.attr('y',function(d){return yScale(d.ceo)+yScale.rangeBand()/2;})
.text(function(d){
return d.startYear;
})
.on('mouseout',function(){d3.select(this).style('opacity','0');})
.on('mouseover',function(){d3.select(this).style('opacity','1');});
)
}else{
console.log('Nothing changed!');
}
});
控制器:
$scope.present = false;
$scope.changePresent = function(){
$scope.present = true;
console.log($scope.present);
};
HTML:
<div ng-graphfingerprint="present" val="data"></div>
现在上面的代码没有用。指令中的一个简单的$ watch也不起作用,所以我想知道在指令中使用$ watch时是否还有其他的东西需要注意。我的编辑器似乎也不喜欢promise.then
回调函数中的$watch
方法。
但基本上我甚至不知道在这种情况下我使用$watch
的策略是否正确。任何人都可以帮助我吗?
如果您需要有关于此问题的任何说明,请告知我们。
答案 0 :(得分:0)
你遇到的问题是该指令有一个隔离范围(scope: {}
),你试图访问父范围的当前属性。
从指令中删除隔离范围或引用隔离范围中的当前属性:
myModule.directive('graphfingerprint', function(){
return {
restrict: 'A',
scope : { present: '=graphfingerprint'},
link: function(scope, element, attrs) {
scope.$watch('present', function(newValue){
});
}
};
});