【问题标题】:AngularJS Extend a controller [closed]AngularJS扩展控制器[关闭]
【发布时间】:2013-12-23 20:34:39
【问题描述】:

我正在使用 Angular 来构建一个大型应用程序,并且我有一些常用的控制器方法,实际上我正在这样做,但存在最好的方法吗?

app.controller('baseController', function($scope, $controller, appFactory) {
    var $scope.foo = function() {
        // Do something
    }
});


app.controller('childController', function($scope, $controller, appFactory) {

    // Here i extend or something like, the base controller

    $controller('baseController', {$scope: $scope});

    var $scope.bar = function() {
        // Do a lot of things an then call foo
        $scope.foo();
    }
}):

我这样做是因为这些方法需要我的控制器的 $scope。

【问题讨论】:

  • 一般常用的方法应该进入提供者(服务,工厂,...)。请记住,Angular 是围绕“在视图和模型之间进行调解”的瘦控制器设计的。如果您能提供更多细节,我可能会给您更具体的建议

标签: javascript angularjs


【解决方案1】:

我不同意上述 cmets 不应该为控制器实现继承。在很多情况下,即使您使用共享的服务/工厂/提供者,控制器继承也会使您的代码保持干燥。使用@Clever 的答案示例,如果可以将其放入单个基本控制器中,为什么要在 X 个控制器中重复 $scope.foo = function() { MyFactory.calculateFoo(); }。这不会使控制器变胖,而是将其清理并保持干燥。

Misko 本人在 AngularJS 谷歌组中给出了这个example,关于控制器继承的一种可能实现。我个人自己使用这个方法,简单的例子,从我的子控制器中调用:

$injector.invoke(MyBaseController, this, { $scope: $scope, alertService: alertService });

我使用控制器继承的示例,对于我的大多数 CRUD 页面,我有一个实现通用创建/更新 $scope 函数的父控制器。这个基本控制器注入了一个存储库服务,它用于执行实际的服务器调用等。为什么要对所有 CRUD 页面一遍又一遍地重复这个?

【讨论】:

  • 我同意在某些情况下,您展示的这个非常有趣的示例从干燥的角度来看是好的。但我担心它很容易脱离理想的瘦控制器。在您的具体示例中,我的问题是 - 服务器调用是否算作“业务逻辑”?如果是这样,我看到 Angular 团队给出的建议是业务逻辑应该进入提供者,而控制器的唯一工作应该是将这些结果映射到视图上。很棒的架构讨论!
  • @KayakDave 我也觉得这个话题很有趣。在我的示例中,服务器调用和任何业务逻辑实际上仍然在提供程序内部实现,基本控制器仅实现提供程序功能的通用/共享映射并将结果映射到视图。所以我相信它符合给出的一般建议。
  • 我没有看到基本控制器的用例。模型和业务逻辑是使用其相应的存储库定义的。为什么控制器甚至会创建/更新 $scope?如果你有一个重复的组件需要控制器上的东西,只需在模板的那部分包含一个控制器或一个指令。
  • @FlavorScape 简单示例,您希望在更新模型后显示通知消息。当然,您不想通过显示 UI 消息来污染您的模型/存储库。因此,在这种情况下,您的控制器可以具有更新范围功能,它将通过您的存储库处理实际更新,并在存储库更新成功/失败时通过您的通知服务显示通知。有许多类似的例子都是这样做的正当理由。
  • @Beyers 在这种情况下,您需要的只是模型上的 $watch 来将事件发送到全局通知指令。这里不需要子类。或者您可以创建一个通知服务并在所有控制器中重新使用它(显式注入与隐式继承)。我看不到控制器包含多态性的情况。您甚至可以在表单中包含一个通用指令,用于监视范围更新和管理通知视图。
【解决方案2】:

详细说明 KayakDave 所说的,Angular 控制器通常是轻量级的。如果您发现自己在控制器中考虑“继承”,那么您可能做错了。最好将控制器之间共享的公共逻辑提取到Service/Factory/Provider 中。例如:

app.Factory('MyFactory', function() {
    return {
        calculateFoo: function() { 
          // stuff 
        }
    };

});

app.controller('FirstCtrl', function($scope, $controller, MyFactory) {
    var $scope.foo = function() {
        MyFactory.calculateFoo();
    }
});


app.controller('SecondCtrl', function($scope, $controller, MyFactory) {

    var $scope.bar = function() {
        MyFactory.calculateFoo();
    }
}):

【讨论】:

    猜你喜欢
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2017-09-26
    • 2013-12-23
    • 2012-01-05
    相关资源
    最近更新 更多