从隔离作用域中删除引用的作用域对象 - angular.js

3

我有一个Angular指令,使用=操作符,将隔离作用域与父级作用域的属性进行双向绑定:

app.directive('nestedDirective', function(){
    return {
        scope: {
            model: '='
        },
        link: function($scope){
            ...
        }
    }
});

我知道对于 $scope.model 的任何更改都会传播到父级作用域。然而,删除 $scope.model 不会传播。delete($scope.model) 因此我的问题是:如何删除引用变量并将其删除操作传播到父作用域。

这个 codepen 示例 应该说明了我想要做的事情(即使不观察作用域也不会触发事件)


然而,删除$scope.model不会传播。 如何删除'$scope.model'? - Neozaru
删除($scope.model),我很想知道更好的方法。您可以在codepen中查看:http://codepen.io/goodafternoon/pen/rneKa - Julian Krispel-Samsel
也许你正在删除“$scope.model”结构,但没有删除该结构指向的值。 尝试使用 $scope.model = null。 - Neozaru
Scope.model = null 是有效的,但我真正需要做的是删除变量而不是将其设置为 null。 - Julian Krispel-Samsel
2个回答

2
这个问题经常被问到,因此我将首先引用 wiki文章
基本上,遵循“点规则”:如果您需要直接修改属性,请将其作为另一个属性的子级进行范围限制,以便启用JS原型继承:
var model = {prop: "val"};
var a = {model: model};

model = null;
console.log(a.model.prop); // prints val

var b = {a: a};
a.model = null;

console.log(b.a.model); // prints null

这里的情况是相同的(即使它不使用原型继承来保持简单)。


如果您查看我所提到的CodePen:http://codepen.io/goodafternoon/pen/rneKa,就会发现情况并不完全相同。我试图删除的项目是父级作用域中数组的一部分,而在Angular中创建隔离作用域的整个目的就是为了隔离它们,沿着原型链向上走会破坏这个目的。 - Julian Krispel-Samsel
你无法取消控制不在手中的东西。只需命名空间模型并将其隔离即可。 - Ven

1
我已经编辑了您的代码pen源代码,我相信有更简单的方法来做到这一点,但我刚刚尝试了这个并且它可以工作,它应该让您走上正确的道路:
<ul ng-app="app" ng-controller="ctrl">
  <dir model="data.children" child="child" ng-repeat="child in data.children"></dir>
</ul>

var app = angular.module('app', []);

app.controller('ctrl', function($scope){
  $scope.data = {};
  $scope.data.children = [
    {name: 'Ben'},
    {name: 'Heffler'},
    {name: 'Schubert'} 
  ];

  $scope.$watchCollection('data.children', function(){
    console.log("children shallow watch", $scope);
  });
  $scope.$watch('data.children', function(){
    console.log("children deep watch",$scope);
  }, true);
});

app.directive('dir', function(){
  return {
    restrict: 'E',
    scope: {
      model: '=',
      child:'='
    },
    replace: true,
    template: '<div>{{child.name}} <button ng-click="remove()">Remove</button></div>',
    link: function(scope, element, attrs){
      scope.remove = function(){
        // I'm just deleting the first one as an example.
        delete(scope.model[0]);
        console.log("children inner scope", scope)
      }
    }
  };
});

我不确定你为什么想要删除这些属性,但我相信你有你的原因,只是想向你展示它是可以实现的。

编辑

这里是经过编辑的 CodePen(请查看控制台日志以查看作用域中已删除的项目)。http://cdpn.io/Ghmvk


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接