【问题标题】:Angularjs capture custom directive data back to controllerAngularjs 将自定义指令数据捕获回控制器
【发布时间】:2017-07-13 17:01:24
【问题描述】:

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

【问题讨论】:

    标签: javascript angularjs d3.js


    【解决方案1】:

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

    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>

    【讨论】:

    • 感谢您的调查,所以我已经用您的答案更新了 plunker 链接,但有一个更改,例如隔离范围替换 = 到 &,因为它是一个函数。出于某种原因,我每次更新时都会变得不确定,然后将 push-data="doPushData" 更改为 push-data="doPushData($value)" 和 scope.pushData(obj);到 scope.pushData({$value:obj})
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多