制作$ scope所持数据的副本

时间:2015-06-23 16:30:09

标签: javascript angularjs

假设我在$scope中有一些变量,我想创建一个包含这些变量的新对象,而没有Angular在$scope中保存的所有内部内容。我不一定知道我要复制的$scope变量的名称。

类似的东西:

$scope.a = "Test";
$scope.b = {x: 1, y: 2};
$scope.c = 99;
//possibly other unknown variables

var obj = angular.copy_without_angular_stuff($scope);

如何获得相关数据?

6 个答案:

答案 0 :(得分:2)

您可以使用

this

而不是

$scope

Plnkr

控制器:

angular.module('myApp').controller('MyCtrl', function(){
  var vm = this;

  vm.a = 'test';

  vm.b = {a: 'a', b: 'b'};

  vm.c = 123;

  var obj = vm;

});

在我看来,我显示了附加到VM的每个值。和VM一样,它只显示a,b和c作为附加到VM的对象。

vm.a: {{vm.a}}
<br/>
vm.b: {{vm.b}}
<br/>
vm.c: {{vm.c}}
<br/>

vm: {{vm}}

<强>更新

如果你没有选择它是否在$ scope上,那么这里是 new plnkr使用$ scope。

控制器:

angular.module('myApp').controller('My2ndCtrl', function($scope) {
  $scope.a = 'test';

  $scope.b = {a: 'a', b: 'b'};

  $scope.c = 123;

  var obj = {};


  for(var k in $scope) {
    if($scope.hasOwnProperty(k) && k.indexOf('$') < 0) {
      obj[k] = $scope[k]
    }
  }
 console.log(obj);
});

然后obj:

{a: "test", b: Object, c: 123}

答案 1 :(得分:1)

$scope对象有一些间隔属性,从$开始,因此解决方法只需复制不是从$开始的属性,甚至可以为内部{创建map {1}}属性和if属性不在map中 - 复制它。
注意:内部属性列表在不同的角度版本中可能有所不同

$scope
angular.module('app', [])
  .controller('ctrl1', function($scope) {
    function clearCopy(scope) {
      var dest = {};
      for (var i in scope) {
        if (scope.hasOwnProperty(i) && i[0] !== '$' && i !== 'this') {
          dest[i] = scope[i];
        }
      }
      return dest;
    }
    $scope.a = "Test";
    $scope.b = {
      x: 1,
      y: 2
    };
    $scope.c = 99;

    $scope.copy1 = clearCopy($scope);
  })
  .controller('ctrl2', function($scope) {
    function clearCopy(scope) {
      var internalProperiesMap = {
          $$ChildScope: true,
          $$childHead: true,
          $$childTail: true,
          $$listenerCount: true,
          $$listeners: true,
          $$nextSibling: true,
          $$prevSibling: true,
          $$watchers: true,
          $$watchersCount: true,
          $id: true,
          $parent: true
        },
        dest = {};
      for (var i in scope) {
        if (scope.hasOwnProperty(i) && !internalProperiesMap[i]) {
          dest[i] = scope[i];
        }
      }
      return dest;
    }
    $scope.a = "Test";
    $scope.b = {
      x: 1,
      y: 2
    };
    $scope.c = 99;
    $scope.copy2 = clearCopy($scope);
  }).controller('ctrl3', function($scope) {
    function clearCopy(scope) {
      var internalProperiesMap = {
        $$ChildScope: true,
        $$childHead: true,
        $$childTail: true,
        $$listenerCount: true,
        $$listeners: true,
        $$nextSibling: true,
        $$prevSibling: true,
        $$watchers: true,
        $$watchersCount: true,
        $id: true,
        $parent: true
      };
      return Object.keys(scope).reduce(function(acc, el) {
        if (el[0] !== '$' && typeof scope[el] !== "function") {
          acc[el] = scope[el];
        }
        return acc;
      }, {});
    }
    $scope.a = "Test";
    $scope.b = {
      x: 1,
      y: 2
    };
    $scope.c = 99;
    $scope.fun = function(d){return d;};

    $scope.copy3 = clearCopy($scope);
  console.log($scope.copy3);
  });

但无论如何它似乎是XY problem

答案 2 :(得分:1)

我无法相信我实际上在暗示这一点。您应该重构代码,这样您就不必这样做了。无论你真的需要这样做......

$scope.test = 4;
var copiedObject = {};
for(var key in $scope){
    if(key[0] != '$' && key != 'this'){
        copiedObject[key] = $scope[key];
    }
}
console.log(copiedObject);

这将遍历所有键并撕掉角度特定的东西。这是一个jsFiddle:

http://jsfiddle.net/n8bz4L7e/

注意:如果您在对象中有引用,或者由于某种原因保存了其他$ scope变量,那么它也会复制它们。正如其他地方提到的那样,这很可能是一个XY问题。

答案 3 :(得分:0)

一种可能的解决方案是将一个对象的属性(在本例中为$ scope)复制到另一个对象中:

for(var k in $scope) {
  secondObject[k] = $scope[k];
}

答案 4 :(得分:0)

如果您对使用下划线感到满意,可以

var obj = _.extendOwn({}, $scope);

否则只需手动复制循环中的属性

var obj = {};

for(var k in $scope) {
    if(Object.prototype.hasOwnProperty.call($scope, k)) {
        obj[k] = $scope[k];   
    }
}

答案 5 :(得分:0)

我省略了范围或任何角度变量(通常以$开头)的任何函数,同时注入$ rootScope,这样就不会有$rootScope$scope的继承属性复制到新对象obj并提出了这个,

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $rootScope) {
   $scope.a = "Test";
$scope.b = {x: 1, y: 2};
$scope.c = 99;
var obj = {};
angular.extend(obj, $scope);
console.log("obj is "+obj);
for(var k in $scope) {
    if(!(Object.hasOwnProperty.call($rootScope, k))) {
if(typeof $scope[k] != "function")
if(k.indexOf("$") != 0){
        obj[k] = $scope[k]; 
console.log("key is "+k);
console.log("value is "+obj[k]);  
    }
}
}
});
</script>