$ watch in directives和activate指令点击

时间:2014-03-07 16:15:38

标签: angularjs d3.js angularjs-directive

我的基本问题是我在指令中有一个d3图表,我希望它在按下按钮提交时显示。指令中的d3代码包含在promise.then中,因为它必须从$http.get(...)请求中获取数据。

现在我的策略是:a-一个按钮,其ng-click属性链接到我的控制器中的函数chnagePresent(); b - 根据指令是否应显示图表,使变量$scope.present取值truefalse;指令内的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的策略是否正确。任何人都可以帮助我吗?

如果您需要有关于此问题的任何说明,请告知我们。

1 个答案:

答案 0 :(得分:0)

你遇到的问题是该指令有一个隔离范围(scope: {}),你试图访问父范围的当前属性。

从指令中删除隔离范围或引用隔离范围中的当前属性:

myModule.directive('graphfingerprint', function(){
    return {
        restrict: 'A',
        scope : { present: '=graphfingerprint'}, 

        link: function(scope, element, attrs) {

            scope.$watch('present', function(newValue){
            });
        }
    };
});