实例化并注入AngularJS控制器

时间:2014-09-01 23:50:29

标签: javascript angularjs angular-ui-bootstrap

我想为多个非常相似的视图使用基础AngularJS控制器,但我想更改传递给每个控制器的Resource

这是基本控制器:

coreAppControllers.controller('ModalEditCtrl',
    function ($scope, $stateParams, Resource, $state, $modalInstance) {
         // A bunch of methods calling Resource
    }
);

现在我想在另一个控制器中使用此控制器,但使用特定于父控制器的Resource

coreAppControllers.controller('MachinesEditCtrl', ['$modal',
    function ($modal) {

        $modal.open({
            backdrop:    'static',
            keyboard:    false,
            templateUrl: '/partials/v1/resources/machines/edit',
            controller:  //ModalEditCtrl with specific Machine resource injected
        });
    }]
);

这可能是在JavaScript中解决此问题的错误方法。在其他语言中,我会扩展一个基类,但我不确定原型语言会是什么。


感谢PSL的答案,但是该方法无法正确注入$modalInstance。最终的解决方案是使用resolve属性,让DI担心其余部分。

出于某种原因,您必须在传递到resolve时将服务包装在匿名函数中。

coreAppControllers.controller('MachinesEditCtrl', ['$modal', 'MachinesAPI',
    function ($modal, MachinesAPI) {
        $modal.open({
            backdrop:    'static',
            keyboard:    false,
            templateUrl: '/partials/v1/resources/machines/edit',
            controller:  'ModalEditCtrl',
            resolve:     {
                Resource: function () {
                    return MachinesAPI;
                }
            }
        });
    }
]);

1 个答案:

答案 0 :(得分:1)

我认为您对DI的关注更多,您可以轻松地这样做: -

说这是你的控制器: -

function ModalEditCtrl($scope, $stateParams, Resource, $state, $modalInstance) {
     // A bunch of methods calling Resource
}
app.controller('ModalEditCtrl',['$scope', '$stateParams', 'Resource', '$state', $modalInstance, ModalEditCtrl]);

只需注册您的特定控制器: -

app.controller('ModalEditCtrlParent1',['$scope', '$stateParams', 'OtherResource', '$state', $modalInstance, ModalEditCtrl]);

app.controller('ModalEditCtrlParent2',['$scope', '$stateParams', 'SomeOtherResource', '$state', $modalInstance, ModalEditCtrl]);

并在你的模态中做: -

   $modal.open({
        backdrop:    'static',
        keyboard:    false,
        templateUrl: '/partials/v1/resources/machines/edit',
        controller:  'ModalEditCtrlParent1'
    });

通过这种方式,您可以让控制器跟随OCP,只需添加新视图,而不是修改现有视图。

以下是使用$controller服务根据您提供的依赖关系获取控制器实例的另一种方法: -

coreAppControllers.controller('MachinesEditCtrl', ['$modal', 'Resource2' function ($modal, Resource) {
        var viewModel = $scope.$new(true);
        $modal.open({
            backdrop:    'static',
            keyboard:    false,
            scope: viewModel,
            templateUrl: '/partials/v1/resources/machines/edit',
            controller: function(){
                 return $controller('ModalEditCtrl', {$scope:viewModel, Resource:Resource});
            } 
        });
    }]
);

<强> Demo

你可以使用任何syntactic sugar for prototypical inheritance(我使用typescript so i generally do extends),但这取决于你想要扩展什么?范围($ scope)或控制器(控制器As)本身(你基本上将扩展视图模型)。