Angularjs将自定义指令数据捕获回控制器

时间:2017-07-13 17:01:25

标签: javascript angularjs d3.js

我在将自定义指令中的数据返回到控制器时面临一个问题,我在每个自定义指令中都有不同的数据图表,我想要的是将每个图表数据放到一个对象中并将其推送到数组中控制器,Plunker。三个对象按预期推入阵列,但每次图表数据对象推送时都会插入一个嵌套数组。我知道有一个声明用于推送每个图表数据的数组,这是正确的方法吗?非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

更好的方法是将一个函数从父控制器传递到更新数组的指令中。您的实现通过更新正在监视的阵列导致问题。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';

  $scope.sampleObject = [{
    name: "Graph1",
    key: "Graph1"
  }, {
    name: "Graph2",
    key: "Graph2"
  }, {
    name: "Graph3",
    key: "Graph3"
  }, ];

  $scope.captureData = [];
  $scope.doPushData = function(newData) {

    $scope.captureData.push(newData);
    console.log($scope.captureData);
  }
  /* 
  $scope.$watch('captureData',function(newValue){
    $scope.captureData.push(newValue);
    console.log($scope.captureData);
  });
  */
});

app.directive('myGraph', function($window) {
  return {
    restrict: 'EA',
    scope: {
      'graphName': '=',
      'pushData': '='
    },
    template: '<div class="lineChart">{{graphName}}</div>',
    link: function(scope, elem, attrs) {
      var d3 = $window.d3;

      // Set the dimensions of the canvas / graph
      scope.margin = {
          top: 30,
          right: 20,
          bottom: 30,
          left: 50
        },
        scope.width = 600 - scope.margin.left - scope.margin.right,
        scope.height = 270 - scope.margin.top - scope.margin.bottom;

      var svg = d3.select(".lineChart")
        .append("svg").attr("width", scope.width + scope.margin.left + scope.margin.right)
        .attr("height", scope.height + scope.margin.top + scope.margin.bottom)
        .append("g")
        .attr("transform", "translate(" + scope.margin.left + "," + scope.margin.top + ")");

      var data = [
        [
          1498102680000,
          6.9
        ],
        [
          1498102710000,
          4.5
        ],
        [
          1498102740000,
          8.4
        ],
        [
          1498102770000,
          4.8
        ],
        [
          1498102800000,
          9.7
        ],
        [
          1498102830000,
          9.6000000000000014
        ],
        [
          1498102860000,
          11.9
        ],
        [
          1498102890000,
          7.1000000000000005
        ],
        [
          1498102920000,
          8.0
        ],
        [
          1498102950000,
          6.2
        ],
        [
          1498102980000,
          5.6
        ],
        [
          1498103010000,
          6.6000000000000005
        ]
      ];

      // Parse the date / time
      var parseDate = d3.time.format("%d-%b-%y").parse;

      // Set the ranges
      scope.xScale = d3.time.scale().range([0, scope.width]);
      scope.yScale = d3.scale.linear().range([scope.height, 0]);

      // Define the axes
      scope.xAxis = d3.svg.axis().scale(scope.xScale)
        .orient("bottom").ticks(5);

      scope.yAxis = d3.svg.axis().scale(scope.yScale)
        .orient("left").ticks(5);

      // Define the line
      scope.valueline = d3.svg.line()
        .x(function(d) {
          return scope.xScale(d[0]);
        })
        .y(function(d) {
          return scope.yScale(d[1]);
        });

      // Scale the range of the data
      scope.xScale.domain(d3.extent(data, function(d) {
        return d[0];
      }));
      scope.yScale.domain([0, d3.max(data, function(d) {
        return d[1];
      })]);

      // Add the valueline path.
      svg.append("path") // Add the valueline path.
        .attr("class", "line")
        .attr("d", scope.valueline(data));

      // Add the X Axis
      svg.append("g") // Add the X Axis
        .attr("class", "x axis")
        .attr("transform", "translate(0," + scope.height + ")")
        .call(scope.xAxis);

      // Add the Y Axis
      svg.append("g") // Add the Y Axis
        .attr("class", "y axis")
        .call(scope.yAxis)

      var obj = {
        graphName: scope.graphName,
        graphData: data
      };

      //scope.spareData.push(obj);
      scope.pushData(obj);
      //console.log(scope.spareData);
    }
  }

});
/* Put your css in here */

body {
  font: 12px Arial;
}

path {
  stroke: steelblue;
  stroke-width: 2;
  fill: none;
}

.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="angular.js@1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <script src="https://d3js.org/d3.v3.min.js"></script>
  <p>Hello {{name}}!</p>
  <div ng-repeat="g in sampleObject">
    <my-graph graph-name="g.name" push-data="doPushData"></my-graph>
  </div>
</body>

</html>