clone下来后:
npm install
启动server执行gulp
运行测试执行 npm run test
生成示例页面:
1.切到gh-pages分支
2.git merge master
3.npm run build:examples
注意:不要在gh-pages做代码修改,这里只用于合进最新代码并生成示例页面
执行npm install bp-utils --save
在入口文件中添加:
import 'bp-utils'
angular.module('yourapp', [
'bp.utils'
])
即可使用以下所有指令和服务
angular angular-ui-tree
- date-view-format
require: ng-model
日期的显示格式 eg: 'YYYY-MM-DD HH:mm:ss'
- date-model-format
require: ng-model
日期的保存格式 eg: 'x'
- bpFieldError
(form-tpl 内使用)
require: ng-model
在表单dirty且invalid在当前表单下或指定容器内展示错误信息
使用示例:
<textarea class="form-control"
ng-model="vm.form[field.name]"
ng-required="field.validateRules.required"
maxlength="{{field.validateRules.maxlength}}"
minlength="{{field.validateRules.minlength}}"
bp-field-error="{{field.errorMsgs}}">
</textarea>
bp-field-error 对常见错误类型的默认展示信息如下:
{
email: '不是有效格式的邮件地址',
url: '不是有效格式的url',
required: '此项不能为空',
same: '此项必须与密码相同',
max: '超过上限',
min: '低于下限',
number: '必须为数字',
parse: '根据验证规则,已重置无效值'
}
使用指令时允许传入自定义错误信息的对象来复写扩展上面默认的eg:
{
min: '最小值不能低于1',
max: '最大值不能超过10',
large: 'number2要大于number1'
}
来自定义错误信息
指定展示错误信息的容器
bp-field-error-selector="{{field.selector}}"
eg:
<input
class="form-control"
type="number"
name="{{field.name}}"
ng-required="field.validateRules.required"
bp-field-error="{{field.errorMsgs}}"
bp-field-error-selector="{{field.selector}}"
bp-large-than="field.validateRules.largeThan"
bp-large-than-form="vm.form"
max="{{field.validateRules.max}}"
min="{{field.validateRules.min}}"
ng-model="vm.form[field.name]">
注意:
bp-field-error和bp-field-error-selector都只接受字符串,而不是表达式
- bpLargeThan
(form-tpl 内使用)
require: ng-model
当前表单内一个字段值要求比另一字段大才和合法时使用;
eg:
<input
class="form-control"
type="number"
name="{{field.name}}"
ng-required="field.validateRules.required"
bp-field-error="{{field.errorMsgs}}"
bp-field-error-selector="{{field.selector}}"
bp-large-than="field.validateRules.largeThan"
bp-large-than-form="vm.form"
max="{{field.validateRules.max}}"
min="{{field.validateRules.min}}"
ng-model="vm.form[field.name]">
bp-large-than和
bp-large-than-form
要配合使用,
bp-large-than传入这样的配置对象:
{
type: 'date', //'number'或'date',决定比较前是否要进行转换
which: 'testDate1' //和哪个字段比较
}
bp-large-than-form传入字段所在form的引用,这样才能找到要比较字段的值
注意:传入的是表达式,指令内部eval
- bp-datepicker
示例:
<bp-datepicker model="vm.time" datepicker-options="vm.datepickerOption" disabled="false"></bp-datepicker>
this.datepickerOption = {
minDate: new Date(),
viewFormat: 'YYYY-MM-DD HH:mm:ss',
modelFormat: 'x',
placeholder: '测试'
};
datepicker-options 传入datepicker配置对象
键名 | 说明 |
---|---|
customClass | ({date: date, mode: mode}) - An optional expression to add classes based on passing an object with date and current mode properties. |
dateDisabled | ({date: date, mode: mode}) - An optional expression to disable visible options based on passing an object with date and current mode properties. |
datepickerMode | (Default: day) - Current mode of the datepicker (day|month|year). Can be used to initialize the datepicker in a specific mode. |
formatDay | (Default: dd) - Format of day in month. |
formatMonth | (Default: MMMM) - Format of month in year. |
formatYear | (Default: yyyy) - Format of year in year range. |
initDate | (Default: now) - The initial date view when no model value is specified. |
maxDate | (Default: null) - Defines the maximum available date. Requires a Javascript Date object. |
maxMode | (Default: year) - Sets an upper limit for mode. |
minDate | (Default: null) - Defines the minimum available date. Requires a Javascript Date object. |
minMode | (Default: day) - Sets a lower limit for mode. |
shortcutPropagation | (Default: false) - An option to disable the propagation of the keydown event. |
minuteStep | (Default: 1) - Number of minutes to increase or decrease when using a button. |
secondStep | (Default: 1) - Number of seconds to increase or decrease when using a button. |
showSeconds | (Default: false) - Show seconds input. |
showSeconds | (Default: false) - Show seconds input. |
viewFormat | 日期的显示格式 默认: 'YYYY-MM-DD HH:mm:ss'; |
modelFormat | 日期的保存格式 默认: 'x' |
- bp-rangepicker
示例:
<bp-rangepicker ng-start-model="vm.startTime"
ng-end-model="vm.endTime"
rangepicker-options="vm.rangepickerOption">
</bp-rangepicker>
this.rangepickerOption = {
viewFormat: 'YYYY-MM-DD HH:mm:ss',
modelFormat: 'x',
placeholder: ['开始时间', '结束时间']
};
支持配置字段同bp-datepicker
- bp-checkboxtree
示例:
<bp-checkboxtree list-promise="vm.loadPromise" ng-model="vm.form.cities" config="vm.config"></bp-checkboxtree>
//拉去列表数据的promise
this.loadPromise = $http.get('/Database/coupon_component/selectCity');
//这个配置用于避免或减少数据转换
this.config = {
//指示子节点的字段名
fieldOfChildren: 'child',
//指示节点名的字段
fieldOfName: 'name',
//指示节点id的字段
fieldOfId: 'categoryId'
};
//约定:所有抛到后端的都放到这个键下
this.form = {};
注意:ng-model中的每条数据必须包含节点id才能正确回填
- multi-select
示例:
<multi-select config="vm.config" ng-model="vm.multiSelectModel"></multi-select>
vm.config = {
//拉取数据的url
url: '/Database/coupon_component/storeQueryList',
//标识每个选项的字段,用于选中选项的查询操作
uniqueField: 'storeId',
//默认返回uniqueField值的数组
//returnModel: 'all',
//生成查询表单的信息w
queryFields: [
{
type: 'text',
displayName: '门店名称',
name: 'storeName'
},
{
type: 'text',
displayName: '商户名称',
name: 'merchantName'
},
{
type: 'text',
displayName: '品牌名称',
name: 'brandNames'
},
{
type: 'text',
displayName: '商圈名称',
name: 'plazaName'
}
],
//在table中展示的字段
tableFields: [
{
displayName: '门店名称',
name: 'storeName'
},
{
displayName: '所属商户',
name: 'merchantName'
},
{
displayName: '经营品牌',
name: 'brandNames'
},
{
displayName: '所属商圈',
name: 'plazaName'
}
],
//ng-table的配置项
tableConfig: {
limit: 10, //每页多少个
pageName: 'page', //后端接受的页码字段名
excel: false //是否需要导出excel
},
//table内的操作按钮
operations: [
{
displayName: '查看',
itemId: 'id', //贫道链接后面的字段
href: '#/city/detail/' //接受三种字段:state, href, action. action函数,接收当前条目id
},
{
displayName: '删除',
itemId: 'id', //标识每一列数据唯一性的字段名,它的值会作为第一个参数传给action
action: function (itemId, tableParams) {
tableParams.parameters({page: 1}).reload();
}
}
],
//获得multiselect controller的引用来初始化this,这个函数会在读取配置后自动执行
// initContrl: that => {
// this.listTableParams = that.tableParams;
// }
};
支持对特定行disable状态的控制: 根据list中isDisable字段来判断
注意:
- 配置中拉取数据的url,在component内使用get请求拉去数据;
- 如果get请求需要传一些固定的参数,我的做法是直接拼在url;
- url拉过来的数据必须符合特定的结构:
eg:{
totalCount: 20088,
items: [
{
brandNames: "我愿意",
storeId: 2036302,
storeName: "I DO",
merchantName: "福建若可投资有限公司(仓山万达珠宝店)",
plazaName: "福州仓山万达广场",
storeNo: null,
businessTypeName: null
},
...
]
}
要保证response.data.items 是一个list;
如果不符合需要转换数据结构,
我的做法:拦截http请求转结构;
推荐使用restangular,提供更方便的api
RestangularProvider.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
let extractedData;
// .. to look for getList operations
if (operation === "getList") {
console.log(data);
// .. and handle the data and meta data
extractedData = data.data;
} else {
extractedData = data;
}
return extractedData;
});
如果后端不符合restful,可以这样:
$httpProvider.interceptors.push(function($q, dependency1, dependency2) {
return {
'request': function(config) {
// do sth
},
'response': function(response) {
// do sth
}
};
});
更详细的介绍见这里:https://docs.angularjs.org/api/ng/service/$http;
自己的做法是尽量把数据转换从业务逻辑剥离放到这;
- form-tpl
<form-tpl form-config="vm.formConfig" model="vm.form"></form-tpl>
form-config传入生成表单的配置,model指定表单的ng-model都绑到哪个键下
示例:
form = {}
formConfig = {
//生成表单的信息,包含验证及对应错误提示的设置
fields: [
{
type: 'text',
displayName: '活动名称',
name: 'testText',
validateRules: {
required: true,
minlength: 0,
maxlength: 50
}
},
{
type: 'text',
displayName: '活动标签',
name: 'tag',
validateRules: {
required: false,
minlength: 0,
maxlength: 50
}
},
{
type: 'radio',
displayName: '营销工具',
name: 'testRadio',
validateRules: {
required: false
},
options: [
{
text: '闪购',
value: 'option1'
},
{
text: '领券',
value: 'option2'
}
]
},
{
type: 'daterange',
displayName: '活动时间',
name: ['startTime, endTime'],
validateRules: {
required: true
}
},
{
type: 'richtext',
displayName: '活动说明',
name: 'testrichtext',
validateRules: {
required: true,
minlength: 1,
maxlenght: 1000
}
},
{
type: 'richtext',
displayName: '活动规则',
name: 'activityrule',
validateRules: {
required: true,
minlength: 1,
maxlenght: 1000
}
},
{
type: 'richtext',
displayName: '活动说明',
name: 'testrichtext',
validateRules: {
required: true,
minlength: 1,
maxlenght: 10
}
},
{
type: 'checkbox',
displayName: '是否公开招募',
name: 'testcheckbox',
validateRules: {
required: false
}
},
{
type: 'image',
displayName: '测试image',
name: 'image',
validateRules: {
required: false
}
}
]
}
- list-tpl
示例:
<list-tpl config="vm.config"></list-tpl>
let vm.Config = {
title: '摇一摇活动列表', //页面标题
//拉取数据的url
url: '/marketcms/shakeCityActivity/getActivityList',
createBtn: {//按钮的权限控制硬编码,并非由配置而来,暂没有想到好的做法
displayName: '创建活动',
href: '#/city/add',
auth: false //注意:只有等于false才会隐藏,undefined或true都会显示,使用 !== false
},
//生成查询表单的信息
queryFields: [
{
type: 'text',
displayName: '活动名称',
name: 'name'
},
{
type: 'uiselect',
displayName: '所属城市',
name: 'cityId',
url: '/marketcms/shakeBase/getCitys',
paramField: 'cityName'
},
{
type: 'text',
displayName: '提交人',
name: 'createUser'
},
{
type: 'select',
displayName: '活动状态',
name: 'status',
options: [
{
text: '全部',
value: ''
},
{
text: '已保存',
value: '1'
},
{
text: '待审批',
value: '2'
},
{
text: '已同意',
value: '3'
},
{
text: '已驳回',
value: '4'
},
{
text: '已暂停',
value: '5'
},
{
text: '已结束',
value: '6'
}
]
},
{
type: 'daterange',
displayName: '活动时间',
name: ['startTime', 'endTime']
}
],
//在table中展示的字段
tableFields: [
{
displayName: '活动编号',
name: 'code'
},
{
displayName: '活动名称',
name: 'name'
},
{
displayName: '开始时间',
name: 'startTime'
},
{
displayName: '截止时间',
name: 'endTime'
},
{
displayName: '提交人',
name: 'createUserName'
},
{
displayName: '所属城市',
name: 'cityName'
},
{
displayName: '活动位置',
name: 'plazaName'
},
{
displayName: '优先级',
name: 'priority'
},
{
displayName: '活动状态',
name: 'status'
}
],
//table内的操作按钮
operations: [
{
displayName: '查看',
href: '#/city/detail/' //接受三种字段:state, href, action. action函数,接收当前条目id
}
]
};
- bpApi
简化和统一$http post和get传递参数的api
用法:
bpApi.post('url', {})
bpApi.get('url', {})
- AlertService
alert, confirm的替代
用法:
AlertService
.alert({
title: "测试",
content: "你好,我是警告"
})
.then(function () {
alert("你刚才点了确定");
});
AlertService
.alert({
title: "测试",
content: "你好,我是警告",
hint: ["操作提示1", "如果想要在操作的时候给点提示,那就写在这里"]
})
.then(function () {
alert("你刚才点了确定");
});
AlertService
.confirm({
title: "测试",
contents: ["你好,确定要删除以下内容吗?", "aaa, bbb"]
})
.then(function () {
alert("你刚才点了确定");
}, function () {
alert("你刚才点了取消");
});
- HintService
消息通知类的alert可以用这个
用法:
HintService.hint({title: "我操作成功了", content: "结果是:" + $scope.hintContent})
- 使用 date-view-format 时格式要保留完整的时间信息,类似 date-view-format="'HH:mm'" 这样的会导致后面的formatter报错,所以必须类似这样的:date-view-format="'YYYY-MM-DD HH:mm'"