在具有链接fn的不同指令中添加指令

时间:2016-05-19 10:07:48

标签: angularjs svg directive

我有一个包装纯JS库的指令。 我想添加另一个指令并将两者结合起来。

目前我有:

指令

app.directive('voPiechart', ['$window', '$compile',
    function ($window, $compile) {
        return {
            restrict: 'E',
            scope: {
                isReady: '=',
                data: '=',
                clickEvent: '='
            },
            link: function ($scope, $elm) {
                var svg = d3.select('#' + $elm[0].id)
                    .append("svg")
                    .append("g");

                svg.append("g")
                    .attr("class", "slices");
                svg.append("g")
                    .attr("class", "labels");
                svg.append("g")
                    .attr("class", "lines");

                /* more directive logic */

                $scope.unselectSlice = function () {
                    $scope.clickEvent(null);
                }
            }
        };
    }
]);

HTML

<vo-piechart id="pie-chart" data="data" is-ready="!isBusy" click-event="sliceSelected" />

现在,我想添加一个名为outside-click的指令,只要我点击一个元素,就会通知我。在这种情况下 - d3创建的SVG元素。

我知道在指令中添加指令通常应该在compile函数中完成,但在这种情况下,我不能继续工作。

我试过这个:

svg.attr('on-outside-click', '{{unselectSlice()');
svg.attr('watch-outside-click', 'true');
$compile(svg)($scope);

它没有用,我似乎在理解指令如何工作时遗漏了一些东西。

我查看了其他类似的问题,但无法将其与我的问题联系起来

- &gt; A working plunkr &lt; -

由于

2 个答案:

答案 0 :(得分:0)

我最终注册了每个切片点击事件和整个svg点击事件并自己处理(没有附加指令)。

这是一个工作小提琴:http://jsfiddle.net/Lvc0u55v/4116/

int k;
int taille = 1;  // TAILLE  A 1  ??
int val;
char caractere;

while (scanf("%d%c", &val, &caractere) > 0 && caractere != '\n') {
    taille++;
} 

printf("taille: %d\n", taille ); //size

int liste[taille];
int permut[taille];

rewind(stdin);    

int j=0;
while (scanf("%d", &k) == 1) {
    if(j < taille){
        liste[j]=k;
    }
    else{
        permut[j-taille]=k;
     }
    j++;
 }

int c=0;

for(c;c<taille;c++){
    printf("per: %d\n", liste[c] );
}

但我仍然希望知道原始问题的答案。

答案 1 :(得分:0)

这种方法怎么样(我没有删除剩下的事件,也许不再需要它们了)

&#13;
&#13;
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', ['$scope', '$timeout', function($scope, $timeout) {
    $scope.data = [{
      label: "Neutral",
      value: 20,
      color: "#FF9E3B",
      from: "-0.3",
      to: "0.3",
      name: "-0.3-0.3"
    }, {
      label: "Negative",
      value: 40,
      color: "#FD2626",
      to: "-0.3",
      name: "*--0.3"
    }, {
      label: "Positive",
      value: 10,
      color: "#0DCF71",
      from: "0.3",
      name: "0.3-*"
    }];

    $scope.sliceSelected = function(data, index) {
      $timeout(function() {
        $scope.selectedSentiment = data != null ? $scope.data.find(function(item) {
          return item.label == data.label;
        }) : null;
      });
    }
    
    $scope.directiveRunTimes = 0;
    
    $scope.thisDirectiveWorks = function() {
       $scope.directiveRunTimes++;
    }
    
  }])
  .directive('onOutsideClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            var stopProp;
            attr.$observe('watchOutsideClick', function (value) {
                //console.log("observed: " + value);
                if (attr.onOutsideClick && attr.watchOutsideClick && scope.$eval(attr.watchOutsideClick)) {
                    $(document).bind('click', function(event) 
                    {
                      if(event.target.nodeName === "path") {
                        event.stopPropagation();
                        return false
                      }
                        console.log("Clciked Anywhere");
                        scope.$apply(function() {
                            scope.$eval(attr.onOutsideClick);
                        });
                    });
                    $(element).bind('click', function(event) {
                        //console.log("In-element click");
                        event.stopPropagation();
                    });
                } else {
                    $(document).unbind('click');
                    $(element).unbind('click');
                }
            });
        }
    }
})
  .directive('voPiechart', ['$window', '$compile',
    function($window, $compile) {
      return {
        restrict: 'E',
        scope: {
          isReady: '=',
          data: '=',
          clickEvent: '='
        },
        link: function($scope, $elm) {
          var container = $($elm[0]).parent();
          var data, width, height, radius, svg, pie, arc, outerArc, key, color;

          $scope.$watch('isReady', function(newVal) {
            if (newVal) {
              if (svg) {
                change(true);
              } else {
                setTimeout(function() {
                  createPiechart();
                }, 100);
              }
            }
          });

          $scope.$watch(function() {
            return $window.outerWidth;
          }, function(newVal, oldVal) {
            if (newVal !== oldVal) {
              createPiechart();
            }
          });

          function createPiechart() {
            duplicateData();

            if (svg) {
              svg.remove();
              $('#' + $elm[0].id).empty();
            }

            updateDimensions();

            /****************************** Important code here! ************************************/

            svg = d3.select('#' + $elm[0].id)
              .append("svg")
              .append("g");

            svg.attr('on-outside-click', '{{unselectSlice()');
            svg.attr('watch-outside-click', 'true');
            $compile(svg)($scope);

            /****************************** end Important code here! ************************************/ 

            svg.append("g")
              .attr("class", "slices");

            pie = d3.layout.pie()
              .sort(null)
              .value(function(d) {
                return d.value;
              });

            arc = d3.svg.arc()
              .outerRadius(radius * 0.8)
              .innerRadius(radius * 0.65);

            outerArc = d3.svg.arc()
              .innerRadius(radius * 0.9)
              .outerRadius(radius * 0.9);

            svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
            change(false);
          }

          function updateDimensions() {
            if (container.width() > 0) width = container.width();
            if (container.height() > 0) height = container.height();
            if (Math.min(width, height) / 2 > 0) radius = Math.min(width, height) / 2;
          }

          function getTotalValues() {
            return data.map(function(item) {
              return item.value;
            }).reduce(function(prev, current) {
              return prev + current;
            }, 0);
          }

          function duplicateData() {
            data = $scope.data.filter(function(item) {
              return item.value > 0;
            });

            if (data.length == 0) {
              data.push({
                label: '$$empty',
                value: 1,
                color: '#f7f8f8'
              })
            }
          }

          function change(shouldDuplicateData) {
            if (shouldDuplicateData) {
              duplicateData();
            }

            var totalValues = getTotalValues();

            key = function(d) {
              return d.data.label;
            };
            color = d3.scale.ordinal()
              .domain(data.map(function(item) {
                return item.label;
              }))
              .range(data.map(function(item) {
                return item.color;
              }));

            /* ------- PIE SLICES -------*/
            var slice = svg.select(".slices").selectAll("path.slice")
              .data(pie(data), key);

            //watch-outside-click="{{ !rangePicker.startDateCollapse || !rangePicker.endDateCollapse }}" o on-outside-click="rangePicker.startDateCollapse = true; rangePicker.endDateCollapse = true;"
            slice.enter()
              .insert("path")
              .style("fill", function(d) {
                return color(d.data.label);
              })
              .attr("class", "slice");

            slice.on("click", function(item, index, alwaysZero) {
              $scope.clickEvent(item.data, index);
            });

            slice
              .transition().duration(1000)
              .attrTween("d", function(d) {
                this._current = this._current || d;
                var interpolate = d3.interpolate(this._current, d);
                this._current = interpolate(0);
                return function(t) {
                  return arc(interpolate(t));
                };
              });

            slice.exit()
              .remove();

            if (data.length == 1 && data[0].label == '$$empty') {
              var text = svg.select(".labels").selectAll("text")
                .remove();
              var polyline = svg.select(".lines").selectAll("polyline")
                .remove();
              return;
            }

          }

          /****************************** Important code here! ************************************/

          $scope.unselectSlice = function() {
            console.log('It worked!');
            alert('workssss');
            $scope.clickEvent(null);
          }
          
          /****************************** end Important code here! ************************************/
        }
      };
    }
  ]);
&#13;
.pie-chart-container {
        position: absolute;
        top: 5px;
        bottom: 5px;
        left: 5px;
        right: 5px;
}

.pie-chart-container svg {
            width: 100%;
            height: 100%;
        }

.pie-chart-container path.slice {
            stroke-width: 2px;
        }

.pie-chart-container polyline {
            opacity: .3;
            stroke: black;
            stroke-width: 2px;
            fill: none;
        }
    
&#13;
<!DOCTYPE html>
<html>

<head>
  <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
  <script src="https://code.angularjs.org/1.4.7/angular.min.js"></script>
  <script src="http://d3js.org/d3.v3.js"></script>
  <link rel="stylesheet" href="style.css">
  <script src="script.js"></script>
</head>

<body ng-app="myApp">

  <div class="pie-chart-container" ng-controller="myCtrl">
    <button on-outside-click="thisDirectiveWorks()" watch-outside-click="true"> mooooooooooooooo {{directiveRunTimes}}</button>
    <div>{{selectedSentiment.label}}</div>
    <vo-piechart id="pie-chart" data="data" is-ready="!isBusy" click-event="sliceSelected"></vo-piechart>
  </div>
</body>

</html>
&#13;
&#13;
&#13;