AngularJS具有基于DOM控制器继承,如在角文档中提到。
<div ng-controller="BaseController">
<p>Base Controller Value: {{value}}</p>
<button ng-click="updateValue()">Update In Base</button>
<div ng-controller="DerivedController">
<p>Derived Controller Value: {{value}}</p>
<button ng-click="updateValue()">Update In Derived</button>
</div>
</div>
范围变量“值”是仅存在于BaseController。 在此基础上,同时改变在BaseController或DerivedController的方法的价值,我想这两个值需要更新。 但是,只有个别的范围变量被更新。
这里是一个小提琴展示同样的例子: http://jsfiddle.net/6df6S/1/
如何能在一个水平的变化进行传播到直接子和电流范围的直接父。
我们可以通过实现这个
$范围。$腕表
有没有办法做到这一点不使用它或任何这样的观察?
编辑1:
通过使用$范围。$看这里就是我的意思
$scope.$watch("value", function () {
$scope.$broadcast("childChangeListener"); //Downwards to all children scopes
$scope.$emit("parentChangeListener"); //Upwards to all parent scopes
});
我一直在寻找方法,使价值会得到所有范围更新,而无需使用这样的机制。
当多个控制器需要访问相同的数据,一个服务应该被使用。 你不应该依赖范围继承,因为它限制了你如何写你的HTML。 例如,在未来,你做决定DerivedController不应该是BaseController的孩子。
您的服务通常应该提供一个公共的API,并隐藏实现。 这使得它更容易重构内部。
HTML:
<div ng-controller="BaseController">
<p>Base Controller Value: {{model.getValue()}}</p>
<button ng-click="model.updateValue('Value updated from Base')">Update In Base</button>
<div ng-controller="DerivedController">
<p>Derived Controller Value: {{model.getValue()}}</p>
<button ng-click="model.updateValue('Value updated from Derived')">Update In Derived</button>
</div>
</div>
JavaScript的:
app.factory('sharedModel', function () {
// private stuff
var model = {
value: "initial Value"
};
// public API
return {
getValue: function() {
return model.value;
},
updateValue: function(value) {
model.value = value;
}
};
});
function BaseController($scope, sharedModel) {
$scope.model = sharedModel;
}
function DerivedController($scope, sharedModel) {
$scope.model = sharedModel;
}
小提琴 。
另外,我建议不要使用$ rootScope的控制器之间共享。
在你的提琴直接结合是在范围内的属性。 你所需要的继承可以通过具有数据的范围对象的结合来实现。
http://jsfiddle.net/2Dtyq/
scope.shared = {}
scope.shared.value = "Something"
而不是只
scope.value= "Something"
怎么了?
虽然DerivedController构造,范围在prototypically继承通过从BaseController的范围。
DerivedController的范围对象仍然没有自己的财产被称为“价值”。 因此,它仍然结合,它从父母的范围得到了财产。
现在,如果你点击更新在基地按钮,它会反映在两个绑定。 是在DerviedController的范围内创建一个网页更新派生按钮的那一刻,一个新的属性命名为“价值”。 因此给母公司值属性的结合被打破。 在更新任何更多的点击次数在基本不刷新第二个数据绑定。
把它在一个单独的对象防止被创建的,因此继承仍然保持新的属性。
您不能直接指到子控制器的字符串值。 由于原型继承设置的属性value
的子范围(当你使用一个子控制器,它被创建)创建属性的子范围,而不是更新父作用域属性。
你的范围是不是模型,因此,我们应避免污染$scope
变量有很多属性。 创建一个模型对象,并在其上创建子属性。 这个对象然后可以沿着子控制器\范围通过。
我修改你的jsfiddle解释上述观点。
此外,我强烈建议你去通过这个wiki页面 ,了解原型继承的滋扰。
看看在$广播方法。 引用文档:
向下分配一个事件名称的所有子作用域(及其子女)通知登记NG。$ rootScope.Scope#$的听众。
使用对象而不是使用原始值。 你的情况,像这样定义一个对象
$scope.obj = {"value":"base"};
并尝试(obj.value)。 它会工作。
这是因为ngController创建一个新的$范围和分值的基准是不一样的。 你可以解决,使用$parent
这样的特性:
<div ng-controller="BaseController">
<p>Base Controller Value: {{value}}</p>
<div ng-controller="DerivedController">
<p>Derived Controller Value: {{$parent.value}}</p>
</div>
</div>
而在DerivedController你可以使用类似的东西: $scope.$parent.value
但是,最好的方式来实现,它是使用controllerAs
语法。
<div ng-controller="BaseController as BaseController ">
<p>Base Controller Value: {{BaseController.value}}</p>
<div ng-controller="DerivedController">
<p>Derived Controller Value: {{BaseController.value}}</p>
</div>
而在DerivedController你可以使用这样的事情: $scope.BaseController.value
这给代码更易读,因为你知道什么是你引用的控制器。 更多关于在ngController文档或挖成角的“控制器”由ToddMotto语法