AngularJS:无法通过指令更改父作用域

时间:2014-07-15 11:55:02

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我正在尝试通过指令更改控制器范围,但它不会更改。

当我通过指令更改模型时,goas将自动更改$scope.modules中的MyCtrl

link: function (scope) {
    scope.module.title += ' changed';

    scope.module = {
        title: 'Redeclared'
    };
},

此代码完美无缺 scope.module.title += ' changed';

但这不是:scope.module = { title: 'Redeclared' };

在$ http.get请求之后,我们有一个{title: 'Redeclared'}的对象,这就是为什么我这样做scope.module = { title: 'Redeclared' };

示例:http://jsfiddle.net/8Va9Q/

知道怎么做吗?感谢

3 个答案:

答案 0 :(得分:5)

您的问题是由于范围/原型继承造成的。

将“module”变量设置为新引用时,新变量将仅在当前范围内已知。在父范围内,'module'变量保持不变。

您可以看到最终结果,例如:

-> parent scope
   -> module = { title: 'foo' }
   -> child scope
       -> module = { title: 'Redeclared' }

相反,如果您只设置'module'变量的title属性,那么将更新父范围上的属性(在'module'变量上)。

如果要覆盖变量,请使用angular.extend(它将覆盖您的对象属性):

angular.extend($scope.module, {
    title: 'Redeclared'
});

你的小提琴是最新的。

关于AngularJS在SO上的范围继承有一个非常好的答案:What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

这是完美的答案,你一定要读这个。

答案 1 :(得分:1)

假设$ rootScope.module === directiveScope.module

那么这个"问题"是因为你引用scope.module而不是改变它:

var original = {name:"original"} ;
var copy = original;// copy is a reference to original (copy === original)
copy.name="copy";//mutating copy changes original
console.log(original.name);//=copy
//re assigning copy de references original
//copy no longer has a reference to original
//and carries it's own value
copy={name:"changed"};
console.log(original.name);//=copy (not changed)

传递对象变量时常见的错误,有时你想要改变它们但是重新分配它们从而引用它们有时候你不想改变它们但是通过改变它们而不小心做(someArray.sort()或someArray.push(" new Item")或someObject.newItem = 88 ...)。

angular.extend不会重新分配scope.module或$ rootScope.module,如下所示:

angular.extend(scope.module, {
    title: 'Redeclared'
});

与...相同但速度慢:

scope.module.title="Redeclared";

如果rootScope.module为{somevar:22},则两个代码示例都会以{somevar:22,title:"Redeclared"}结尾 它可以用于必须使用收到的json对象改变scope.module的情况:

scope.module.prop1 = receivedJSON.prop1;
scope.module.prop2 = receivedJSON.prop2;
//...many more
scope.module.prop100 = receivedJSON.prop100;

将会缩短很多时间:

angular.extend(scope.module, receivedJSON);

答案 2 :(得分:0)

所有关于JavaScript数据类型: 在这里你改变了链接(scope.module)提供的对象选项

scope.module.title 

在这里你完全重写了整个对象(没有链接)

scope.module

所以对你来说最好这样做: 不

   $scope.modules = [{
        title: 'test 0'
    }, {
        title: 'test 1'
    }, {
        title: 'test 2'
    }];

$scope.modules.push(title: 'test 0'})
$scope.modules.push(title: 'test 1'})
$scope.modules.push(title: 'test 2'})