Angular.js:在ng-repeat内的子控制器中,如何传播模型更改

时间:2014-03-04 20:19:57

标签: javascript angularjs restangular

在我的角度应用程序中,我使用的是ng-repeat,并且每个内部都有一个子控件,每个项目都有一个表单。我也使用去抖动,以便我可以自动保存数据。但问题是在保存数据(使用Restangular)之后,更改不会传播回父级中的数组。一个简单的例子可以使用angular.copy,但这有Restangular的问题,它的替换,Restangular.copy,功能完全不同。我也尝试将项目显式设置为数组上的右侧索引,但它会导致我的光标在输入中失去焦点。

这是我的子控制器代码的简化版本。并且here is a full JS Bin。还有另一种方法可以解决这个问题吗?

$scope.personCopy = angular.copy($scope.person);

// Debounce and auto-save changes
$scope.$watch('personCopy', function(newVal, oldVal) {
  if (newVal && newVal != oldVal) {
    if (timeout) $timeout.cancel(timeout);
    timeout = $timeout(savePerson, 1000);
  }
}, true);

var savePerson = function() {
  // (In my real app, the following is inside a save callback)
  // Method 1: (doesn't work at all)
  $scope.person = $scope.personCopy
  // Method 2: (works with angular.copy, but not Restangular.copy)
  // angular.copy($scope.personCopy, $scope.person);
  // Method 3: (works, but cursor loses focus)
  // $scope.people[$scope.$index] = $scope.personCopy;
};

2 个答案:

答案 0 :(得分:4)

如果您在ng-repeat中添加“track by”,方法3将适用于您:

<li ng-repeat='person in people track by $index' ng-controller='EditPersonController'>

这就是工作:http://jsbin.com/jitujaro/3/edit

您失去焦点的原因是当您更新ngRepeat时正在重新创建people的DOM。所以关注的元素已经消失了。使用track by时Angular知道它不需要重新创建那些DOM元素。

方法1和2不起作用的原因是Javascript的原型继承。写入父作用域上的变量后,将在本地作用域上创建该变量的新本地副本。但是,当写入父作用域上的对象的属性时(就像在方法3中那样),写入会在父对象上发生,如预期的那样。

答案 1 :(得分:1)

尝试

angular.extend($scope.person, $scope.personCopy);

而不是

$scope.person = $scope.personCopy;