AngularJS:如何将长控制器拆分成模块?

时间:2014-09-21 04:22:32

标签: javascript angularjs model-view-controller model

构建我的第一个角度应用程序,我不明白如何将代码拆分成更小的块。我只有一个长的运行控制器,但如果我尝试将代码分成不同的部分(控制器,服务等),突然数据不再绑定到视图(即我更新数据,但是更改未在视图/浏览器中显示。

即。我有一个简单的应用程序连接到api以获取" Books"列表,然后显示列表,并允许用户使用分页导航,或获取单个书籍的更多详细信息,或更新书籍记录(编辑/删除)。

我想将这些功能拆分为单独的控制器,如:

  • 搜索控制器:处理表单验证,$ http到api;
  • 图书(列表):显示搜索结果的结果;
  • 预订(单个)控制器:图书清单中的每个项目都是一个项目,其中包含"更多细节"和"编辑/删除";
  • 分页控制器:功能到next / prev通过图书清单;
  • 消息控制器:在"搜索","预订"或"分页&#中执行操作时显示成功/错误消息34;控制器。

麻烦的是我不知道如何设置它,因为如果我使用服务来存储/输出"书籍"模型或"消息"当我通过其中一个控制器对这些数据进行更新时,更改不会自动更新视图(就像我更新链接到控制器的$ scope变量一样)。

根据我的理解,视图中的$ scope变量会自动更新,因为ng-controller="MyCtrl"绑定到某个区域。但是如何使用服务呢?你没有使用ng-service标签,对吧......?

所以,让我说我的searchController调用api,收到所有书籍的json。我将其推入booksService进行存储。然后我的booksController,负责更新页面上所有书籍的列表视图,必须加载这个booksService来获取新数据......但是它如何知道数据已更新?如何链接booksService中的数据,通过booksController,以在视图中显示新结果?

此外,我将如何构建booksService - 如何让searchController传递新数据(更新我可以用于模型的持久变量),然后如何让booksController加载那个新数据?我是否需要在booksService中创建一个调用以将新数据推送到booksController,或者booksController是否应该调用从booksService中提取新数据(如果是这样,它将如何知道何时应该进行PULL)?

同样,searchController和paginationController将使用匹配查询对相同的API进行GET调用(唯一的区别是查询中的$ page变量)。我应该使用'服务' (或者它是工厂?)来解耦$ http.get请求?

最后,在文件夹/文件结构中构建所有这些控制器/服务的最佳方法是什么?我是否应该将每个块分隔到单独的* .js文件中?我应该使用require.js导入文件吗?在这种情况下,它是一个网站的单个页面(在网站上可能还有其他类似的页面)。如果我将代码拆分为单独的文件,我应该根据每个网页将文件分组到一个文件夹中吗? (即如果我添加"用户仪表板"页面,所有文件将存储在"搜索书籍页面中的单独文件夹中。

抱歉,我知道我已经提出了很多要求,但这确实有助于我理解正确构建Angular应用程序所涉及的概念。

1 个答案:

答案 0 :(得分:4)

将所有控制器以这种方式放在controller.js文件中。

angular.module('starter.controllers', [])

.controller('SearchCtrl', function($scope) {
    //do your search stuff
})
.controller('BookCtrl',function($scope){

})
.controller('PaginationCtrl',function($scope){

})
.controller('MessagesCtrl',function($scope){

});

//in your services.js file

angular.module('starter.services', [])

/**
 * A simple  service that returns some data.
 */

.factory('Search', function() {

  var somedata="from service";

  return {
    sample: function() {
         return somedata;
       }
    }
)};

您可以从任何类似的控制器调用工厂服务

.controller('SearchCtrl', function($scope, Search) {
//get data from factory service
    $scope.getdata=Search.sample();

})

也在您的指令文件

/*
its route map for the application 
all the page navigation are done here
common for the application 
*/
angular.module('app',[
'ui.router'
])
.config(['$urlRouterProvider','$stateProvider',function($urlRouterProvider,$stateProvider){

    $urlRouterProvider.otherwise('/');
    $stateProvider
    .state('home',{
        url:'/',
            templateUrl:'templates/home.html',
            controller:'SearchCtrl'
        })
        .state('about',{
        url:'/about',
            templateUrl:'templates/about.html',
            controller:'aboutCtrl'      
        })

}])

在home.html中,您可以通过这种方式阅读数据

<h2>{{$scope.getdata}}</h2>

查看此链接(http://ionicframework.com/getting-started/)并尝试使用模拟基于标签的应用程序工作的示例tabs应用。对于此类应用,带有angularjs的离线框架效果更佳。