为了账号安全,请及时绑定邮箱和手机立即绑定

AngularJS(二、如何用AngularJS建立前端代码框架)

标签:
JavaScript

     我们可以看到scripts中分列了一下几个文件夹:controllers、services、directives、filters、vendor,以及两个文件app.js和main.js。

    controllers里面主要就是控制器

   services里面是服务,为控制器提供数据服务支持,与后台交互的代码就在其中

    directives是指令,用于生成自定义标签的html模板

    filters是过滤器,用于处理显示数据的形式

    vendor文件夹中存放的是引用的第三方js插件

跟scripts同级的是styles和views文件夹,styles存放css样式文件,view存放html文件。


    我们先来看一下index.html中的主要代码:

<!DOCTYPE html><html> <!-- Do not add ng-app here as we bootstrap AngularJS manually--><head>  <title>My AngularJS App</title>  <meta charset="utf-8" />  <link rel="stylesheet" type="text/css"        href="styles/bootstrap.min.css">  <link rel="stylesheet" type="text/css" href="styles/ng-grid.css" />  <link rel="stylesheet" type="text/css" href="styles/main.css"></head><body class="home-page row-fluid"><nav class="navbar navbar-default">    ……</nav><div class="col-lg-10 col-md-12 col-sm-12 col-sm-12 col-lg-offset-1">    <div ng-view></div></div><div class="row-fluid"></div>  <script data-main="scripts/main"        class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="scripts/vendor/require.js"></script></body></html>

我们可以看到导入的js只有一个require.js,但是这个script中有个这样的属性 

data-main="scripts/main"

这个属性就将主js指向了scripts/main.js。

下面来看main.js,其中,分为了两块,第一块是对第三方的引用和依赖配置:

// the app/scripts/main.js file, which defines our RequireJS configrequire.config({    paths:{        angular:'vendor/angular.min',        jquery:'vendor/jquery',        bootstrap:'vendor/bootstrap.min',        domReady:'vendor/domReady',        ngGrid:'vendor/ng-grid.debug'    },    shim:{        angular:{            deps:[ 'jquery'],            exports:'angular'        },        ngGrid:{            deps:[ 'jquery']        },        bootstrap:{            deps:[ 'jquery']        }    }});

第二块就是主要的引用和route信息了:

require([    'angular',    'app',    'domReady',    'bootstrap',    'services/userService',    'controllers/rootController',    'directives/ngbkFocus',    'controllers/user/listController',    'controllers/user/editController',    'controllers/user/newController',    'ngGrid'    // Any individual controller, service, directive or filter file    // that you add will need to be pulled in here.],    function (angular, app, domReady) {        'use strict';        app.config(['$routeProvider',            function ($routeProvider) {                $routeProvider.when('/', {                    templateUrl:'views/user/list.html',//当跳转到该路径时,将此html嵌入到ng-view属性的dom中                    controller:'ListCtrl'//当前templateUrl的controller为ListCtrl                })                    .when('/edit/:name/:allowance', {                        templateUrl:'views/user/form.html',                        controller:'EditCtrl'                    })                    .when('/new', {                        templateUrl:'views/user/form.html',                        controller:'NewCtrl'                    })                    .when('/root', {                        templateUrl:'views/root.html',                        controller:'RootCtrl'                    });            }        ]);        domReady(function () {            angular.bootstrap(document, ['MyApp']);//app名为MyApp            // The following is required if you want AngularJS Scenario tests to work            $('html').addClass('ng-app: MyApp');//给html添加ng-app属性        });    });

以list的route为示例,我们来讲解controller,先看一张list效果图(此处我们引用了ng-grid插件):来看引入的controllers/user/listController:

define(['controllers/controllers', 'services/userService'],    function (controllers) {        controllers.controller('ListCtrl', ['$scope', '$http', '$location', 'UserService',//此处数组中的参数依次对应下面回调方法中的参数            function ($scope, $http, $location, UserService) {                                $scope.mySelections = [];                $scope.filterOptions = {                    filterText:"",                    useExternalFilter:true                };                $scope.totalServerItems = 0;                $scope.pagingOptions = {                    pageSizes:[250, 500, 1000],                    pageSize:250,                    currentPage:1                };                $scope.setPagingData = function (data, page, pageSize) {                    var pagedData = data.slice((page - 1) * pageSize, page * pageSize);                    $scope.myData = pagedData;                    $scope.totalServerItems = data.length;                    if (!$scope.$$phase) {                        $scope.$apply();                    }                };                $scope.getPagedDataAsync = function (pageSize, page, searchText) {                    setTimeout(function () {                        var data;                        if (searchText) {                            var ft = searchText.toLowerCase();                            UserService.getServerData(function (largeLoad) {                                data = largeLoad.filter(function (item) {                                    return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;                                });                                $scope.setPagingData(data, page, pageSize);                            });                        } else {                            UserService.getServerData(function (largeLoad) {                                $scope.setPagingData(largeLoad, page, pageSize);                            });                        }                    }, 100);                };                $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);                $scope.$watch('pagingOptions', function (newVal, oldVal) {                    if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {                        $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);                    }                }, true);                $scope.$watch('filterOptions', function (newVal, oldVal) {                    if (newVal !== oldVal) {                        $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);                    }                }, true);                                $scope.clickme = function (v) {                    $location.path('/edit/' + v.name + "/" + v.allowance);                }                $scope.gridOptions = {                    data:'myData',                    enablePaging:true,                    showFooter:true,                    totalServerItems:'totalServerItems',                    pagingOptions:$scope.pagingOptions,                    filterOptions:$scope.filterOptions,                    selectedItems:$scope.mySelections,                    showSelectionCheckbox:true,                    columnDefs:[                        { field:"name", pinned:true }                        ,                        { field:"allowance", cellTemplate:'<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD | currency}}</span></div>'}                        ,                        { field:"entity", pinned:true, cellTemplate:'<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{$parent.row.entity | myfilter}}</span></div>' }                        ,                        { field:"name", width:100, cellTemplate:'<button class="btn-xs table-btn" ng-click="clickme($parent.row.entity)"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>'}                    ]/*,                    multiSelect:false*/                };            }]);    });

其中定义了该controller名为ListCtrl,$scope为局部变量,其中定义的数据与方法可在当前Ctrl作用域内生效,我们来看一下生效的list.html是怎么样的

<div class="gridStyle" ng-grid="gridOptions"></div>

就是这么一句话,定义了grid的div,其余的都交给了controller和ng-grid插件

listController中引用了services/userService,service层用来与后台交互,管理数据:

define(['services/services'],    function (services) {        services.factory('UserService', ['$http',            function ($http) {                return {                    getData:function () {                        return [                            { name:"Moroni", age:50, birthday:"Oct 28, 1970", salary:"60,000" },                            { name:"Tiancum", age:43, birthday:"Feb 12, 1985", salary:"70,000" },                            { name:"Jacob", age:27, birthday:"Aug 23, 1983", salary:"50,000" },                            { name:"Nephi", age:29, birthday:"May 31, 2010", salary:"40,000" },                            { name:"Enos", age:34, birthday:"Aug 3, 2008", salary:"30,000" },                            { name:"Moroni", age:50, birthday:"Oct 28, 1970", salary:"60,000" },                            { name:"Tiancum", age:43, birthday:"Feb 12, 1985", salary:"70,000" },                            { name:"Jacob", age:27, birthday:"Aug 23, 1983", salary:"40,000" },                            { name:"Nephi", age:29, birthday:"May 31, 2010", salary:"50,000" },                            { name:"Enos", age:34, birthday:"Aug 3, 2008", salary:"30,000" },                            { name:"Moroni", age:50, birthday:"Oct 28, 1970", salary:"60,000" },                            { name:"Tiancum", age:43, birthday:"Feb 12, 1985", salary:"70,000" },                            { name:"Jacob", age:27, birthday:"Aug 23, 1983", salary:"40,000" },                            { name:"Nephi", age:29, birthday:"May 31, 2010", salary:"50,000" },                            { name:"Enos", age:34, birthday:"Aug 3, 2008", salary:"30,000" }                        ];                    },                    getOptions:function () {                        return {                            data:'myData',                            enablePinning:true,                            columnDefs:[                                { field:"name", width:120, pinned:true },                                { field:"age", width:120 },                                { field:"birthday", width:120 },                                { field:"salary", width:120 }                            ]                        }                    },                    getServerData:function (success) {                        $http.get('jsonFiles/largeLoad.json').success(success);                    },                    saveData:function (data, success) {                        $http.post('/users/save', data).success(success);                    }                };            }]);    });

其中引用的$http是用来管理ajax的对象,类似的对象还有$location,用来管理url地址,类似的对象还有很多,详细可以参见官方API文档。

    至此,一个前端MVC框架基本构建完成,在之后的一篇中我们来着重介绍下还没讲过的filters和directives。




点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消