2014-03-07 64 views
0

我的基本問題是,我有一個指令內的d3圖,我希望它顯示按鈕提交時按下。指令中的d3代碼被封裝到promise.then中,因爲它必須從$http.get(...)請求中獲取數據。

現在我的策略是: - 一個按鈕,其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時是否還有其他值得注意的事情。我的編輯器似乎也不喜歡$watch回調函數中的promise.then方法。 但基本上我甚至不知道在這種情況下我的使用$watch的策略是否正確。誰能幫我?

如果您需要關於該問題的任何澄清請讓我知道。

回答

0

您遇到的問題是該指令具有隔離範圍(scope: {}),並且您試圖訪問父範圍的當前屬性。

無論是從指令取出分離範圍,或在隔離範圍內引用本屬性:

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

     link: function(scope, element, attrs) { 

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

由於它的作品! – user1718064