angular规范

2016/1/17 20:09
规范1:

将每个模块定义在一个单独的独立的文件中

//不推荐
angular
    .module('app', ['ngRoute'])
    .controller('SomeController', SomeController)
    .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }
                    **推荐1**
// app.module.js
angular
    .module('app', ['ngRoute']);
// some.controller.js
angular
    .module('app')
    .controller('SomeController', SomeController);

function SomeController() { }
// someFactory.js
angular
    .module('app')
    .factory('someFactory', someFactory);

function someFactory() { }

在推荐1中有一个问题,那就是function暴露在window下,像这样

/* 不推荐*/
// logger.js
angular
    .module('app')
    .factory('logger', logger);

// logger function is added as a global variable
function logger() { }

// storage.js
angular
    .module('app')
    .factory('storage', storage);

// storage function is added as a global variable
function storage() { }

所以为了解决这个弊端,就应该将文件定义在一个立即执行的函数中

/**
* 推荐
*
* 将不会存在全局变量
*/

// logger.js
(function() {
    'use strict';

    angular
        .module('app')
        .factory('logger', logger);

    function logger() { }
})();

// storage.js
(function() {
    'use strict';

    angular
        .module('app')
        .factory('storage', storage);

    function storage() { }
})();

规范2

不使用变量进行模块的定义

/* 不推荐 */
var app = angular.module('app', [
    'ngAnimate',
    'ngRoute',
    'app.shared',
    'app.dashboard'
]);
/* 推荐(使用简单的语法)*/
angular
    .module('app', [
        'ngAnimate',
        'ngRoute',
        'app.shared',
        'app.dashboard'
    ]);

规则:3

使用命名函数代替回调函数

//避免
angular
    .module('app')
    .controller('DashboardController', function() { })
    .factory('logger', function() { });
//推荐
// dashboard.js
angular
    .module('app')
    .controller('DashboardController', DashboardController);

function DashboardController() { }
// logger.js
angular
    .module('app')
    .factory('logger', logger);

function logger() { }

规范4
使用 controllerAs 语法、


<div ng-controller="CustomerController">
    {{ name }}
div>

<div ng-controller="CustomerController as customer">
    {{ customer.name }}
div>

当使用controllerAs的时候定义一个变量代替视图模型$scope

/* avoid */
    function courseController (){
    this.name = 'course';
    this.customers = [
        {name: 'Haley'}, {name: 'Ella'}, {name: 'Landon'}, {name: 'John'}
        ];
    }

    angular.module('app')
    .controller('courseController', courseController)
/* 推荐*/
function courseController (){
    var vm = this;
    vm.name = 'course';
    vm.customers = [
        {name: 'Haley'}, {name: 'Ella'}, {name: 'Landon'}, {name: 'John'}
        ];
    }

angular.module('app')
    .controller('courseController', courseController)
/* 避免*/
function SessionsController() {
    var vm = this;

    vm.gotoSession = function() {
      /* ... */
    };
    vm.refresh = function() {
      /* ... */
    };
    vm.search = function() {
      /* ... */
    };
    vm.sessions = [];
    vm.title = 'Sessions';
}
/* 推荐*/
function SessionsController() {
    var vm = this;

    vm.gotoSession = gotoSession;
    vm.refresh = refresh;
    vm.search = search;
    vm.sessions = [];
    vm.title = 'Sessions';

    

    function gotoSession() {
      /* */
    }

    function refresh() {
      /* */
    }

    function search() {
      /* */
    }
}

规范5

声明函数隐藏实现细节

/**
* avoid
* Using function expressions.
*/
function AvengersController(avengersService, logger) {
    var vm = this;
    vm.avengers = [];
    vm.title = 'Avengers';

    var activate = function() {
        return getAvengers().then(function() {
            logger.info('Activated Avengers View');
        });
    }

    var getAvengers = function() {
        return avengersService.getAvengers().then(function(data) {
            vm.avengers = data;
            return vm.avengers;
        });
    }

    vm.getAvengers = getAvengers;

    activate();
}
/*
* recommend
* Using function declarations
* and bindable members up top.
*/
function AvengersController(avengersService, logger) {
    var vm = this;
    vm.avengers = [];
    vm.getAvengers = getAvengers;
    vm.title = 'Avengers';

    activate();

    function activate() {
        return getAvengers().then(function() {
            logger.info('Activated Avengers View');
        });
    }

    function getAvengers() {
        return avengersService.getAvengers().then(function(data) {
            vm.avengers = data;
            return vm.avengers;
        });
    }
}

延迟逻辑。保持控制器苗条

/* avoid */
function OrderController($http, $q, config, userInfo) {
    var vm = this;
    vm.checkCredit = checkCredit;
    vm.isCreditOk;
    vm.total = 0;

    function checkCredit() {
        var settings = {};
        // Get the credit service base URL from config
        // Set credit service required headers
        // Prepare URL query string or data object with request data
        // Add user-identifying info so service gets the right credit limit for this user.
        // Use JSONP for this browser if it doesn't support CORS
        return $http.get(settings)
            .then(function(data) {
             // Unpack JSON data in the response object
               // to find maxRemainingAmount
               vm.isCreditOk = vm.total <= maxRemainingAmount
            })
            .catch(function(error) {
               // Interpret error
               // Cope w/ timeout? retry? try alternate service?
               // Re-reject with appropriate error for a user to see
            });
    };
}
/* recommended */
function OrderController(creditService) {
    var vm = this;
    vm.checkCredit = checkCredit;
    vm.isCreditOk;
    vm.total = 0;

    function checkCredit() {
       return creditService.isOrderTotalOk(vm.total)
          .then(function(isOk) { vm.isCreditOk = isOk; })
          .catch(showError);
    };
}

规范6

**
确保一个控制器对应一个view ,相同逻辑应该放在服务service中,尽量确保控制器的简洁;
**

规范7 每个服务都是单例,说明每个注入到控制器,指令的服务相互不影响

服务返回一个对象
服务的定义语法糖

// service
angular
    .module('app')
    .service('logger', logger);

function logger() {
  this.logError = function(msg) {
    /* */
  };
}
// factory
angular
    .module('app')
    .factory('logger', logger);

function logger() {
    return {
        logError: function(msg) {
          /* */
        }
   };
}
angular.
module('myServiceModule', []).
 controller('MyController', ['$scope','notify', function ($scope, notify) {
   $scope.callNotify = function(msg) {
     notify(msg);
   };
 }]).
factory('notify', ['$window', function(win) {
   var msgs = [];
   return function(msg) {
     msgs.push(msg);
     if (msgs.length == 3) {
       win.alert(msgs.join("\n"));
       msgs = [];
     }
   };
 }]);

规范7 暴露服务返回的对象的成员属性在最上面;隐藏函数实现的细节

angualr.module('app').
    factory('dataService',dataService)
function dataService() {
    var someValue = '';
    var service = {
        save: save,
        someValue: someValue,
        validate: validate
    };
    return service;

    /隐藏函数实现的细节///

    function save() {
        /* */
    };

    function validate() {
        /* */
    };
}

**

指令

**

定义一个指令;

用指令的名字命名文件名字
将一个指令单独放在一个文件中
在指令中操作dom
定义指令的时候:最好定义一个清晰独一无二的名字像这样
acmeSalesCustomerInfo 在html中运用的时候需要这样写
acme-sales-customer-info

/* avoid */
/* directives.js */

angular
    .module('app.widgets')

    /* order directive that is specific to the order module */
    .directive('orderCalendarRange', orderCalendarRange)

    /* sales directive that can be used anywhere across the sales app */
    .directive('salesCustomerInfo', salesCustomerInfo)

    /* spinner directive that can be used anywhere across apps */
    .directive('sharedSpinner', sharedSpinner);

function orderCalendarRange() {
    /* implementation details */
}

function salesCustomerInfo() {
    /* implementation details */
}

function sharedSpinner() {
    /* implementation details */
}
/* recommended */
/* calendar-range.directive.js */

/**
* @desc order directive that is specific to the order module at a company named Acme
* @example 
*/
angular .module('sales.order') .directive('acmeOrderCalendarRange', orderCalendarRange); function orderCalendarRange() { /* implementation details */ } /* recommended */ /* customer-info.directive.js */ /** * @desc sales directive that can be used anywhere across the sales app at a company named Acme * @example
*/
angular .module('sales.widgets') .directive('acmeSalesCustomerInfo', salesCustomerInfo); function salesCustomerInfo() { /* implementation details */ } /* recommended */ /* spinner.directive.js */ /** * @desc spinner directive that can be used anywhere across apps at a company named Acme * @example
*/
angular .module('shared.widgets') .directive('acmeSharedSpinner', sharedSpinner); function sharedSpinner() { /* implementation details */ }

定义指令的时候,建议restrict: ‘EA’;因为这样会有语义化,而class就没有了;向下面这样

/* recommended */
angular
    .module('app.widgets')
    .directive('myCalendarRange', myCalendarRange);

function myCalendarRange() {
    var directive = {
        link: link,
        templateUrl: '/template/is/located/here.html',
        restrict: 'EA'
    };
    return directive;

    function link(scope, element, attrs) {
      /* */
    }
}

定义路由的最佳方式

/* better */

// route-config.js
angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'AvengersController',
            controllerAs: 'vm',
            resolve: {
                moviesPrepService: function(movieService) {
                    return movieService.getMovies();
                }
            }
        });
}

// avengers.js
angular
    .module('app')
    .controller('AvengersController', AvengersController);

AvengersController.$inject = ['moviesPrepService'];
function AvengersController(moviesPrepService) {
    var vm = this;
    vm.movies = moviesPrepService.movies;
}

定义文件名字的规范

/**
 * recommended
 */

// controllers
avengers.controller.js
avengers.controller.spec.js

// services/factories
logger.service.js
logger.service.spec.js

// constants
constants.js

// module definition
avengers.module.js

// routes
avengers.routes.js
avengers.routes.spec.js

// configuration
avengers.config.js

// directives
avenger-profile.directive.js
avenger-profile.directive.spec.js

推荐的项目目录

用于展示一个功能的文件都放在一根文件夹目录

/**
 * recommended
 */

app/
    app.module.js
    app.config.js
    components/
        calendar.directive.js
        calendar.directive.html
        user-profile.directive.js
        user-profile.directive.html
    layout/
        shell.html
        shell.controller.js
        topnav.html
        topnav.controller.js
    people/
        attendees.html
        attendees.controller.js
        people.routes.js
        speakers.html
        speakers.controller.js
        speaker-detail.html
        speaker-detail.controller.js
    services/
        data.service.js
        localstorage.service.js
        logger.service.js
        spinner.service.js
    sessions/
        sessions.html
        sessions.controller.js
        sessions.routes.js
        session-detail.html
        session-detail.controller.js

模块依赖

angular规范_第1张图片

$

Use $document and $window instead of document and window.
Use $timeout and $interval instead of setTimeout and setInterval .

你可能感兴趣的:(angualr,angular)