2013-12-23 138 views
4

使用angular来构建一个大的应用程序,我有一些常见的控制器方法realy即时做到这一点,但存在一个最好的方式来做到这一点?AngularJS扩展控制器

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

我这样做,因为这个方法需要有我的控制器的de $范围。

+1

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

+0

请参阅此线程http://stackoverflow.com/questions/16539999/angular-extending-controllers – user2923779

回答

3

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

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

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

的,我用控制器继承,对于大多数我的CRUD的网页我有一个实现通用创造一个单亲控制器的一个例子/更新$范围函数。这个基础控制器获得注入的资源库服务,用于执行实际的服务器调用等等。为什么对于所有的CRUD页面反复重复这个问题?

+0

我同意有些情况下,这样的事情真的你从一个干燥的角度展示了一个有趣的例子。但是我担心它可以轻松地摆脱瘦控制器的理想。在你的具体例子中,我的问题是服务器调用算作“业务逻辑”吗?如果是这样的话,我所看到的Angular团队的建议是业务逻辑应该进入提供商,而控制器的唯一工作就是将这些结果映射到视图上。伟大的建筑讨论! – KayakDave

+0

@KayakDave我也觉得这个话题很有趣。在我的示例中,服务器调用和任何业务逻辑实际上仍然在提供者中实现,基础控制器只是实现提供者功能和结果在视图上的通用/共享映射。所以我相信它符合一般建议。 – Beyers

+0

我没有看到基本控制器的用例。模型和业务逻辑使用相应的存储库进行定义。为什么控制器甚至会创建/更新$范围?如果您有重复的组件需要控制器上的某些内容,那么只需将控制器或指令包含在模板的该部分中即可。 – FlavorScape

1

为了阐述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(); 
    } 
}):