angualr|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 语法、
{{ name }}

{{ customer.name }}

当使用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 someValuehttps://www.it610.com/article/= ''; 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

模块依赖 【angualr|angular规范】angualr|angular规范
文章图片

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

    推荐阅读