AngularJS控制器继承(AngularJS controller inheritance)

2019-07-21 11:58发布

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
});

我一直在寻找方法,使价值会得到所有范围更新,而无需使用这样的机制。

Answer 1:

当多个控制器需要访问相同的数据,一个服务应该被使用。 你不应该依赖范围继承,因为它限制了你如何写你的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的控制器之间共享。



Answer 2:

在你的提琴直接结合是在范围内的属性。 你所需要的继承可以通过具有数据的范围对象的结合来实现。

http://jsfiddle.net/2Dtyq/

scope.shared = {}    
scope.shared.value = "Something"

而不是只

scope.value= "Something"

怎么了?
虽然DerivedController构造,范围在prototypically继承通过从BaseController的范围。
DerivedController的范围对象仍然没有自己的财产被称为“价值”。 因此,它仍然结合,它从父母的范围得到了财产。
现在,如果你点击更新在基地按钮,它会反映在两个绑定。 是在DerviedController的范围内创建一个网页更新派生按钮的那一刻,一个新的属性命名为“价值”。 因此给母公司值属性的结合被打破。 在更新任何更多的点击次数在基本不刷新第二个数据绑定。
把它在一个单独的对象防止被创建的,因此继承仍然保持新的属性。



Answer 3:

您不能直接指到子控制器的字符串值。 由于原型继承设置的属性value的子范围(当你使用一个子控制器,它被创建)创建属性的子范围,而不是更新父作用域属性。

你的范围是不是模型,因此,我们应避免污染$scope变量有很多属性。 创建一个模型对象,并在其上创建子属性。 这个对象然后可以沿着子控制器\范围通过。

我修改你的jsfiddle解释上述观点。

此外,我强烈建议你去通过这个wiki页面 ,了解原型继承的滋扰。



Answer 4:

看看在$广播方法。 引用文档:

向下分配一个事件名称的所有子作用域(及其子女)通知登记NG。$ rootScope.Scope#$的听众。



Answer 5:

使用对象而不是使用原始值。 你的情况,像这样定义一个对象

$scope.obj = {"value":"base"}; 

并尝试(obj.value)。 它会工作。



Answer 6:

这是因为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语法



文章来源: AngularJS controller inheritance