【问题标题】:AngularJS is cross-binding variables?AngularJS 是交叉绑定变量吗?
【发布时间】:2016-03-02 01:58:37
【问题描述】:

我通过使用 Promises 下载 JSON 数据并将其存储在变量中来开始我的 Angular 控制器:

app.controller('mainController', ['$scope', '$http', '$q', function($scope, $http, $q) {
  var req1 = $http({method: 'GET', url: 'link to JSON 1', cache: 'true'});
  var req2 = $http({method: 'GET', url: 'link to JSON 2', cache: 'true'});

  $q.all([req1, req2]).then(function(response){
    var res1 = response[0].data;
    var res2 = response[1].data;

    $scope.data1 = res1;       // JSON which I will manipulate
    $scope.data1Ref = res1;   // JSON for reference which I won't manipulate

    $scope.data2 = res2;
    $scope.data2Ref = res2;

    init(); // do the stuff with the data
  });
}]);

然而,在init() 完成后,如果我检查$scope.data1$scope.data1Ref 它们都已被修改,那就是它们被绑定在一起了。

为什么会发生这种情况?如何确保保留原始下载 JSON 的存储版本以供参考?

【问题讨论】:

  • 这是因为 $scope.data1 和 $scope.data1Ref 引用了 res1 所以对 res1 的任何更改都会反映在这两个中。您需要在分配 res1 之前对其进行复制。

标签: javascript angularjs angularjs-scope angularjs-bindings


【解决方案1】:

这是因为在 JavaScript 中,对象是通过引用传递的。当您将 $scope.data1 和 $scope.data1Ref 设置为 res1 时,您将它们设置为等于 res1 的 reference

要解决此问题,您可以使用 angular.copy 制作 res 对象的深层副本。

$scope.res1Ref = angular.copy(res1);

【讨论】:

  • 有趣的是,angular.copy() 似乎需要相当长的时间来运行(在这种情况下几乎是 4000 毫秒),而不是再次下载 JSON。因此,至少在这种情况下,潜在的解决方法是下载 JSON 两次。
  • 其他人发现了一个更快的克隆算法:github.com/angular/angular.js/issues/11099 另外,lodash 有一个你可以尝试的深度克隆函数,_.cloneDeep() lodash.com/docs#cloneDeep
  • 非常感谢你,保罗布林。使用来自github.com/angular/angular.js/issues/11099 的代码已导致性能显着提高。
【解决方案2】:

当你对对象使用赋值时,你只是给变量一个对象的引用,而不是复制对象。在您的代码中,$scope.data1$scope.data1Refres1 都指向完全相同的对象实例。要创建新对象,您需要复制现有对象。

Angular 提供了两个可以复制对象的函数,一个创建浅拷贝,另一个创建深拷贝。浅拷贝复制原始字段,如果对象包含子对象,则原始和副本都指向同一个子对象实例。在深层副本中,任何子对象也会创建新副本。

angular.extend 可用于创建浅拷贝,而angular.copy 可用于创建深拷贝。

【讨论】:

    【解决方案3】:

    在 AngularJS 中,复杂对象是通过引用传递的。你可以在这里找到更多信息:Difference between angular.copy() and assignment (=)

    【讨论】:

      猜你喜欢
      • 2012-12-02
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 2015-10-22
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      相关资源
      最近更新 更多