我需要从指令中的父控制器继承范围。我不一定要留下范围:false。我也不一定要使用隔离范围,因为需要大量工作才能使我关心的值正确链接(在父控制器中考虑很多值)。
如果我想更新父范围,在我的指令中使用scope:true
是否有意义?
<div ng-controller="MyCtrl">
Hello, {{name}}!
<my-directive></my-directive>
</div>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Dave';
}
myApp.directive('myDirective', function() {
return {
scope: true,
restrict: 'EA',
link: function(scope, elem, attrs) {
scope.updateName = function(newName) {
console.log('newName is: ' + newName);
scope.name = newName;
}
},
template: '<input ng-model="updatedName" placeholder="new name value"> <button ng-click="updateName(updatedName)">Update</button>'
}
})
请查看fiddle
答案 0 :(得分:50)
虽然@ user1737909已经引用了SO问题(What are the nuances of scope prototypal / prototypical inheritance in AngularJS?,它将解释问题并推荐各种方法来修复它),但我们通常会尝试在SO上给出答案。
所以,你的小提琴不起作用的原因是因为当原始类型(即字符串,数字或布尔类型)被写入 - 例如scope.name = newName
时 - “写”总是转到本地范围/对象。换句话说,子作用域具有自己的name
属性,该属性会隐藏同名的父属性。修复是在父作用域中使用对象而不是基本类型。然后,子范围将获得对该对象的引用。对对象属性的任何写入(无论是来自父对象还是子对象)都将转到该对象。 (子范围没有自己的对象。)
$scope.obj = {name: 'Dave'};
然后在你的指令中:
scope.obj.name = newName;
和HTML:
Hello, {{obj.name}}!
答案 1 :(得分:15)
范围继承并不意味着设置子的值是设置其父级的值。
不是在子作用域上执行scope.name = newName
,而是向父作用域添加一个方法,该作用域将在父作用域上执行相同的作业,并从子作用域调用它,因为子作用继承了此方法。
答案 2 :(得分:6)
在您的链接函数中,您将写入父作用域(全局“$ scope”作用域),如下所示:scope。$ parent.name = newName;