简体   繁体   English

AngularJS:不能通过指令更改父范围

[英]AngularJS : can not change parent scope via directive

I am trying to change the controllers scope via directive but it does not change. 我正在尝试通过指令更改控制器范围,但不会更改。

The goas is to change the $scope.modules in MyCtrl automaticly when i am changing model via directive: 当我通过指令更改模型时, MyCtrl自动更改$scope.modules中的$scope.modules

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

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

This code works perfectly scope.module.title += ' changed'; 这段代码可以正常工作scope.module.title += ' changed';

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

After $http.get request we have an object with {title: 'Redeclared'} thats why i am doing so scope.module = { title: 'Redeclared' }; 在$ http.get请求之后,我们有了一个带有{title: 'Redeclared'}的对象,这就是我这样做的原因scope.module = { title: 'Redeclared' };

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

Any idea how to do this? 任何想法如何做到这一点? Thanks 谢谢

Your problem is due to scope / prototype inheritance. 您的问题是由于范围/原型继承。

When you set the 'module' variable to a new reference, your new variable will be known in your current scope only. 当您将“模块”变量设置为新引用时,新变量将仅在您当前的作用域中被知道。 On the parent scope, the 'module' variable remained untouched. 在父作用域上,“模块”变量保持不变。

You can see the final result such as: 您可以看到最终结果,例如:

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

Instead, if you only set the title attribute of your 'module' variable, then the attribute (on the 'module' variable) on the parent scope will be updated. 相反,如果仅设置“模块”变量的title属性,则父作用域上的属性(在“模块”变量上)将被更新。

If you want to override the variable, use angular.extend (it will override your object attributes) : 如果要覆盖变量,请使用angular.extend(它将覆盖对象属性):

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

Your fiddle is up to date. 您的小提琴是最新的。

There is a really good answer about scope inheritance with AngularJS on SO here: What are the nuances of scope prototypal / prototypical inheritance in AngularJS? 关于AngularJS在SO上的作用域继承,这里有一个很好的答案:AngularJS 中作用域原型/原型继承的细微差别是什么?

This is the perfect answer, and you should definitely read this. 这是一个完美的答案,您绝对应该阅读此内容。

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

Then this "problem" is because you de reference scope.module instead of mutating it: 那么这个“问题”是因为您引用了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)

A common mistake when passing object variables, sometimes you want to mutate them but re assign them and thereby de reference them and sometimes you don't want to change them but accidentally do by mutating them (someArray.sort() or someArray.push("new Item") or someObject.newItem=88 ...). 传递对象变量时的常见错误,有时您想要对其进行变异,然后重新分配它们,从而取消引用它们;有时您不想更改它们,但偶然地通过对它们进行变异(someArray.sort()或someArray.push( “新项目”)或someObject.newItem = 88 ...)。

angular.extend does not re assign scope.module or $rootScope.module, the following: angular.extend不会重新分配scope.module或$ rootScope.module,如下所示:

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

Is the same as but slower than: 与以下相同但较慢:

scope.module.title="Redeclared";

If rootScope.module was {somevar:22} then both code examples would end up with {somevar:22,title:"Redeclared"} It could be used for a situation where you have to mutate scope.module with a received json object: 如果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;

Would be a lot shorter with: 使用以下命令会更短:

angular.extend(scope.module, receivedJSON);

it's all about JavaScript data types: here you change option of object that is provided by link (scope.module) 这都是关于JavaScript数据类型的:在这里,您可以更改链接(scope.module)提供的对象的选项

scope.module.title 

and here you totally rewrite the whole object (no link) 在这里,您完全重写了整个对象(无链接)

scope.module

So for you case it's better to do: not 因此,对于您而言,最好这样做:不

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

but

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM