Angular - 从另一个控制器调用特定于控制器的函数的最佳实践是什么?

时间:2015-10-30 18:21:51

标签: javascript angularjs

我对Angular比较新。我制作了一个应用程序,它在表单中获取数据并将其保存为MongoDB中的对象。我有一个侧边栏的控制器和指令,它始终存在于应用程序中,列出了所有已保存的对象。在这个控制器中,我有一个更新列表的函数:

$scope.refreshList = function(){
  //http call to database & refresh list accordingly
};

然后为了使该功能可以从其他控制器调用,我有这个:

$window.refreshList = $scope.refreshList;

因此,例如,我可以从表单提交函数中调用$window.refreshList来在提交新对象时更新表单。

我觉得这可能不是最好的做法。什么是最好的方法,记住refreshList函数依赖于列表控制器中定义的一些变量?

3 个答案:

答案 0 :(得分:2)

要在应用程序的不同部分共享功能,您应该使用服务。

例如:

app = angular.module( 'app' );

app.service( 'Backend', [ function () {
    this.refreshList = function () {
      //http call to database & refresh list accordingly
    };
} ] );

app.controller( 'Controller1', [ '$scope', 'Backend', function ( $scope, Backend ) {
    Backend.refreshList().then( function ( results ) {
        // work with the results and the scope here
    } );
} );

// And reuse the code in other controllers
app.controller( 'Controller2', [ '$scope', 'Backend', function ( $scope, Backend ) {
    Backend.refreshList().then( function ( results ) {
        // work with the results and the scope here and do something different
    } );
} );

答案 1 :(得分:2)

Angular is a framework which simplifies things for you. It has its own guidelines on how the code should be organized, hence there are concepts of scope, controllers, services etc

Now coming back to your question, on how to make two controllers communicate or share data between them, or how to call one controller function from another controller ?

First assume you have two controllers, one main controller which controls the index page which has got side bars (your list side bar), top bar and a view where we load all the other pages.

So your basic structure would be as follows,

  <div id="main" ng-controller="MainController">
     <nav id="sideBar"> <!-- Your list where items are dynamically shown --></nav>
     <div id="view" ng-view><!-- This is where you will load your templates dynamically --></div>
   </div>

Now any server call within should be placed in service so this can be called from any controller just by injecting the service and its not tightly coupled with one particular controller. So your call for refreshList will be in a service.

  app.service("serverCalls", function(){
     this.refreshListFromServer = function() {
         // Logic to get data from server and returning promise which can be resolved in your controller.
      }
   })

Now assuming your main controller has a method $scope.refreshList() which will call your method from service serverCalls.refreshListFromServer() and refresh your side bar.

$scope.refreshList = function() {
 serverCalls.refreshListFromServer().then(function(){
   // logic to handle response returned from server.
 })
}

Now if form is being submitted by another controller (may be form controller) then you may want to reload your side bar once the form is successfully submitted, to achieve this, you can set up a listener on one of the method in MainController as follows,

//This will get the dataObj, sent by emitter.
$scope.$on("refreshSideBar", function(event, dataObj){
  $scope.refreshList(dataObj);
})

And in your FormController, you can emit the event which will be picked by the listener we sat up above in MainController.

//dataObj can be any arbitrary data you want to pass to listener.
$scope.$emit("refreshSideBar", dataObj);

$emit: Dispatches an event name upwards through the scope hierarchy notifying the registered $rootScope.Scope listeners.

答案 2 :(得分:0)

这不是控制器的使用方式。 Controller始终绑定到单个视图。如果您要在整个应用程序中共享数据或功能,则应考虑使用服务。

最好有一个服务来处理对服务器的所有调用。 然后,您可以在需要访问api调用的每个控制器中导入服务。