Angular:继承方法扩展子控制器范围

时间:2017-06-14 22:21:56

标签: javascript angularjs inheritance controller

我遇到了一个问题,这个问题让我对一些角度子控制器中延伸的方法感到不安。我的主要目标是从父控制器继承所有公共/ $ scope /变量和方法到子控制器,但扩展一些具有更多逻辑的特定函数。所以这就是我的一般情况:

var app = angular.module("conrollersInheritance", []);

app.controller("parentController", [
    "$scope",
    function ($scope) {
        /* PRIVATE */
        var privateVar1 = "private variable 1";
        var privateVar2 = "private variable 2";

        // ...Some other private stuff here...

        /* PUBLIC */
        $scope.publicVar1 = "public variable 1";
        $scope.publicVar2 = "public variable 2";

        $scope.showVars = function () {
            console.log("PRIVATE: ", privateVar1, privateVar2);
            console.log("PUBLIC: ", $scope.publicVar1, $scope.publicVar2);
        };

        // ...Some other public stuff here...
    }
]);

app.controller("childController", [
    "$scope", "$controller",
    function ($scope, $controller) {
        $controller("parentController", { $scope: $scope });

        $scope.showVars = function () {
            alert("child scope");
            // ???Here I want to execute the inherited method from the `parentController`
        };
    }
]);

基本上,childController继承了$scope中的所有parentController数据,这很好,但我似乎无法扩展继承的功能,但总是覆盖它。我尝试了不同的方法来解决问题,因为我从Angular文档中看到$controller服务应该返回实例/ https://docs.angularjs.org/api/ng/service/ $ controller /,但在我的情况下,它总是返回一个空的构造对象。所以当我尝试在childController

中做这样的事情时
var parentController = $controller( "parentController", { $scope: $scope } );

我总是为parentConroller变量获取一个emtpy对象,我不能使用从那里继承的任何东西。试图在childController中使用viewmodel声明,如下所示:

var vm = this;
$controller( "parentController", { vm: $scope } );
angular.extend( $scope, vm );

但似乎也不是正确的决定,因为它在尝试扩展范围时会抛出错误,我也不能做这样的事情:

$scope.showVars = function() {
    alert( "child scope" );
    vm.showVars();
};

所以,我有点困惑,我怎么能这样做。我阅读了很多教程,声称上面的方法应该可行,但在我的情况下看起来并不像这样。那么,有什么想法吗? 谢谢!

1 个答案:

答案 0 :(得分:1)

Thanks to prototypical inheritance, your child controller inherits all parent's properties/methods from the $scope by default, if your controllers are nested.

You can nest controllers by either using ui-router and defining a child state

.state('route', {
    controller: 'ParentController',
    // the rest of the route config
})

.state('route.child', {
    controller: 'ChildController',
    // the rest of the route config
})

or by nesting them in the template

<div ng-controller="ParentController">
    <div ng-controller="ChildController">
        <!-- the rest of your template -->
    </div>
</div>

Then you can simply extend your ParentController method like this:

$scope.showVars = () => {
    $scope.$parent.showVars();
    // your other logic
};

That will create a a showVars method on your ChildController's $scope which will be used by default by your template instead of the one inherited fro mthe ParentController.