当obj.id发生变化时,obular.id的AngularJS:ng-repeat轨道不会重新初始化被转换的内容

时间:2016-09-07 12:12:01

标签: angularjs angularjs-ng-repeat ng-repeat



function ComponentController() {
  var vm = this;
  this.$onInit = function() {
    vm.link = 'http://example.com/obj/' + vm.obj.id;
  }
}
function MainController($scope, $timeout) {
  $scope.arrObjs = [{id: 1, name: "object1"},{id: 2, name: "object2"}];
    console.log('object1\'s id is ', $scope.arrObjs[0].id);
  $timeout(function() { // simulates a call to server that updates the id
    $scope.arrObjs[0].id = '3';
    console.log('object1\'s new id is ', $scope.arrObjs[0].id, '. Expected the link above to be updated with the new ID');
  }, 1000);
}
var someComponent = {
  bindings: {
    obj: '='
  },
  template: '<div>URL: <span>{{$ctrl.link}}</span></div>',
  controller: ComponentController
};

angular.module('myApp', []);
angular
    .module('myApp')
    .controller('MainController', MainController)
    .controller('ComponentController', ComponentController)
    .component('someComponent', someComponent);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="MainController">
    <div ng-repeat="obj in arrObjs track by obj.id">
      <some-component obj="obj"></some-component>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

ng-repeat及其someComponent呈现其中一个对象之后&#39; obj.id更改(使用上例中的$timeout)。该对象的vm.link仍带有旧ID!

现在,我知道$onInit()只在someComponent内运行一次,但为什么track by重新初始化组件,因为obj.id已更改?

如果Angular真的通过obj.id跟踪了一个数组,它应该将obj的id更改为一个完全不同的对象并重新初始化它,不是吗?

显然$watch中的vm.obj.id someComponent会修复它,但有没有办法再添加$watch

注意:之前我正在使用

<div ng-repeat="objID in vm.arrObjIDs track by objID" ng-init="obj = vm.fnLookUpObjByID(objID)">
  <someComponent obj="obj"></someComponent>
</div>

这完美无缺!这正是我期望track by obj.id工作的方式。但我试图摆脱ng-init模式。

1 个答案:

答案 0 :(得分:0)

您错过了代码中某些您未向我们展示的内容。

以下代码段有效。

init()不是标准函数。你可能意思是<dx:ASPxComboBox ID="cbx_Organization" runat="server" ValueType="System.String" Width="230px"> <ClientSideEvents SelectedIndexChanged="function(s, e) { handleOrganizationChange(); }" /> </dx:ASPxComboBox>

&#13;
&#13;
$onInit()
&#13;
function ComponentController() {
  var vm = this;
  console.log("not in init: " + this.obj.id);
  this.$onInit = function() {
    console.log("in init: " + vm.obj.id);
  }
}
function MainController($scope) {
  $scope.arrObjs = [{id: 1, name: "object1"},{id: 2, name: "object2"}];
}
var someComponent = {
  bindings: {
    obj: '='
  },
  template: '<div>ID: <span>{{$ctrl.obj.id}}</span></div>',
  controller: ComponentController
};

angular.module('myApp', []);
angular
    .module('myApp')
    .controller('MainController', MainController)
    .controller('ComponentController', ComponentController)
    .component('someComponent', someComponent);
&#13;
&#13;
&#13;

编辑:

如果在中间添加异步函数,则编译代码将始终比异步函数的返回更快。

使用$ watch是数据更改时更新视图的标准方法。 除此之外别无其他。

注意:对于组件,您可以使用$ onChanges(),但在这种特殊情况下,它不会触发,因为您必须change the reference of the object才能更新。 $ onChanges()在任何情况下都会调用$ watch。