您的位置:首页 > Web前端 > AngularJS

angular规范

2016-01-17 21:32 761 查看
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 <div acme-order-calendar-range></div>
*/
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 <div acme-sales-customer-info></div>
*/
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 <div acme-shared-spinner></div>
*/
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


模块依赖



$

Use $document and $window instead of document and window.
Use $timeout and $interval instead of setTimeout and setInterval .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: