AngularJS ng-repeat不会重新呈现转发器(UI),也不会再次调用ng-init

时间:2016-12-08 11:32:44

标签: javascript angularjs angularjs-ng-repeat google-pie-chart

我对print (df.sort_values('date') .groupby('name')['quantity'] .apply(lambda x: x.diff().mean()) .reset_index()) name quantity 0 'A' -2.5 1 'B' NaN 有一点疑问,实际上我有一些图表。

  1. 趋势热线
  2. 下面的Piecharts。
  3. 下面的HTML表格。
  4. 页面加载我没有显示任何内容,但是一旦我第一次点击特定按钮,我的整个图表和表格都会显示为http请求收到的数据。但之后如果我点击另一个按钮并执行相同的http请求,那么它会更新趋势线和表,但不会更新饼图。 我的饼图用ng-init在下面的div中呈现,当我测试ng-init =" myFunction(index)"方法在后续点击时不会更新。

    ng-init

    这是ng-init函数的angularjs代码。

    <form>
      <md-input-container>
        <label for="myInput">Search Division</label>
        <md-icon md-svg-icon="~/Content/myIcons/searchicon/ic_search_black_36px.svg"></md-icon>
        <input type="text" id="myInput" ng-model="searchDiv" md-autofocus>
      </md-input-container>
      <md-content ng-repeat="prod in listofProd | filter: searchDiv">
        <md-button class="md-whiteframe-1dp card" ng-click="generateChart(prod)" flex-sm="100" flex-gt-sm="100" flex-gt-md="100">
        {{prod}}
        </md-button>
      </md-content>
    </form>
    
    <div layout="row" layout-wrap>
      <div flex="25" style="width:1000px;height:300px; border: 1px solid skyblue;" ng-repeat="year in years track by $index" id="piechart{{$index}}" ng-init="myFunction($index)">
      </div>
    </div>
    

2 个答案:

答案 0 :(得分:1)

  

Angular 1.2起,它有一个选项track by来阻止转发器   从重新渲染所有项目以提高性能。

可在以下网址找到更多信息:http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/

这就是为什么ng-init因为您在years track by ng-repeat="year in years track by $index"使用了ng-init而再次针对相同的years被解除的原因。

即使你删除了这个,Angular也是第二次没有被触发,因为track by这里的数组是years非常精彩,可以跟踪它的值,尽管有没有明确的object array

因此,我们必须将[{year: obj.SecuredYear}]从简单数组更改为$$hashKey,例如ng-init,让Angular生成<div flex="25" style="width:1000px;height:300px; border: 1px solid skyblue;" ng-repeat="year in years" id="piechart{{$index}}" ng-init="myFunction($index)"> </div> ,当对象更改时,years不相同每次和Angular都会通过触发 var years = []; json.forEach(function (obj) { var exists = years.filter(function(y) { return y.year === obj.SecuredYear; }); if (exists.length === 0) { // This will replace the `indexOf` check years.push({year: obj.SecuredYear}); // change here } }); $scope.years = years; 来重绘转发器。

所以与此相关的变化是,

<强> HTML

      $scope.myFunction = function (index) {
      var data = [['Product', 'ValueInDhs']];
      json.forEach(function (obj) {
        if (obj.SecuredYear == years[index].year) {   // change here at years[index].year
          data.push([String(obj.GroupName).trim(), obj.ValueInDhs]);
        }
      });
      $scope.displayChart(data, index);
    };

JS (填充console.log(years[index].year);

$scope.myFunction()

JS (myFunction())

ng-init

我刚刚创建了一个示例代码段,如下所示:Generate Chart内的angular.module('myApp', []); function MyCtrl($scope) { var json = [{SecuredYear: 1965},{SecuredYear: 1988}, {SecuredYear: 2016}, {SecuredYear: 2012}]; $scope.generateChart = function(item) { var years = []; json.forEach(function (obj) { var exists = years.filter(function(y) { return y.year === obj.SecuredYear; }); if (exists.length === 0) { years.push({year: obj.SecuredYear}); } }); $scope.years = years; $scope.myFunction = function (index) { var data = [['Product', 'ValueInDhs']]; json.forEach(function (obj) { if (obj.SecuredYear == years[index].year) { //data.push([String(obj.GroupName).trim(), obj.ValueInDhs]); console.log(years[index].year); } }); //$scope.displayChart(data, index); }; }; }<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp"> <div ng-controller="MyCtrl"> <button ng-click="generateChart()">Generate Chart</button><br/> <div style="border: 1px solid skyblue;" ng-repeat="year in years" id="piechart{{$index}}" ng-init="myFunction($index)" >{{year.year}} </div> </div> </div>成功对话,每次按下{点击{1}}。

&#13;
&#13;
{{1}}
&#13;
{{1}}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

angular.module('app', [
    'googlechart'
  ])
  .controller('appCtrl', function() {
    let vm = this;
    vm.charts = [];

    vm.addChart = function() {
      vm.charts.push({
        type: "PieChart",
        data: {
          "cols": [{
            id: "t",
            label: "Topping",
            type: "string"
          }, {
            id: "s",
            label: "Slices",
            type: "number"
          }],
          "rows": [{
            c: [{
              v: "Mushrooms"
            }, {
              v: 3
            }, ]
          }, {
            c: [{
              v: vm.input.name
            }, {
              v: vm.input.quantity
            }]
          }, {
            c: [{
              v: "Olives"
            }, {
              v: 31
            }]
          }, {
            c: [{
              v: "Zucchini"
            }, {
              v: 1
            }, ]
          }, {
            c: [{
              v: "Pepperoni"
            }, {
              v: 2
            }, ]
          }]
        }
      });
    };
    return vm;
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-google-chart/0.1.0/ng-google-chart.min.js" type="text/javascript"></script>
<div ng-app="app" ng-controller="appCtrl as vm">
  <div ng-repeat="chart in vm.charts track by $index">
    <div google-chart chart="chart" style="height:150px; width:100%;"></div>
  </div>
  <br>
  <input type="text" required ng-model="vm.input.name" placeholder="Enter name">
  <input type="number" required ng-model="vm.input.quantity" placeholder="Enter quantity">
  <button ng-click="vm.addChart()">Add chart</button>
</div>

我注意到你正在使用谷歌图表。您的问题源于使用不兼容的库(谷歌图表不知道模型中的变化 - 在这种情况下是角度)。

可以编写自己的指令,但为什么如果其他人已经完成了繁重的工作?相反,我建议您考虑使用以下directive

这是一个live示例。

修改:ng-init 以您希望的方式工作。 ng-init只需在控制器加载时触发一个函数,而不是在渲染元素时触发。