UNPKG

bat-ria

Version:

RIA extension for Brand Ads Team

328 lines (296 loc) 9.89 kB
/** * @file 表单类型`Action`基类 * @author chestnutchen(chenli11@baidu.com) */ define(function (require) { var util = require('er/util'); var u = require('underscore'); var Deferred = require('er/Deferred'); var BaseAction = require('./BaseAction'); /** * 表单类型`Action`基类 * * @extends BaseAction * @constructor */ function FormAction() { BaseAction.apply(this, arguments); } util.inherits(FormAction, BaseAction); /** * 设置表单提交成功后显示的信息,如果值为`null`或`undefined`则表示不显示任何信息 * * 如果该字段有内容,则系统使用该字段与提交表单后服务器返回的数据进行模板格式化, * 因此可以使用服务器返回的字段为占位符。模板使用`underscore.template`方法 * * @type {string | false | null} */ FormAction.prototype.toastMessage = ''; /** * 获取表单提交成功后显示的信息 * * 默认提示信息为“保存成功” * * @param {Object} result 提交后服务器端返回的信息 * @return {string} */ FormAction.prototype.getToastMessage = function (result) { var message = this.toastMessage; if (message == null) { return ''; } if (message) { return u.template(message, result || {}); } else { return '保存成功'; } }; /** * 处理提交数据成功后的返回 * * @param {Object} result 提交成功后返回的内容 */ FormAction.prototype.handleSubmitResult = function (result) { var toast = this.getToastMessage(result); if (toast) { this.view.showToast(toast); } if (typeof this.redirectAfterSubmit === 'function') { this.redirectAfterSubmit(result); } }; /** * 默认提交/取消后跳转的路径 * @type {string} */ FormAction.prototype.backLocation = null; /** * 执行提交成功后的跳转操作 * 在有referrer的情况下跳转至referrer * 在没有referrer的情况下history.back() * * 可在业务action里边重写 * * @param {Object} result 提交后服务器返回的数据 */ FormAction.prototype.redirectAfterSubmit = function (result) { this.back(this.backLocation, true); }; /** * 处理提交错误 * * @param {Object} message 失败时的message对象 */ FormAction.prototype.handleSubmitError = function (message) { if (message && message.field) { this.view.notifyErrors(message.field); this.view.handleValidateInvalid(); } this.view.showToast('保存失败'); }; /** * 处理本地的验证错误 * 没有name的controls请自行扩展处理 * * @param {Object|string} errors 本地验证得到的错误信息 * object视为`FieldError`,string视为`GlobalError` * object的格式: * { * name1: errorMessage1, * name2: errorMessage2 * } * * @return {Mixed} 本地验证得到的错误信息 */ FormAction.prototype.handleLocalValidationErrors = function (errors) { if (typeof errors === 'string') { this.view.alert(errors, '系统提示'); } else if (typeof errors === 'object') { this.view.notifyErrors(errors); } return errors; }; /** * 重置的操作 */ FormAction.prototype.reset = function () { var reset = this.fire('reset'); if (!reset.isDefaultPrevented()) { this.view.rollbackFormData(this.model.getDefaultData()); } }; /** * 设置取消编辑时的提示信息标题 * * @type {string} */ FormAction.prototype.cancelConfirmTitle = '确认取消编辑'; /** * 获取取消编辑时的提示信息标题 * * @return {string} */ FormAction.prototype.getCancelConfirmTitle = function () { return this.cancelConfirmTitle; }; /** * 设置取消编辑时的提示信息内容 * * @type {string} */ FormAction.prototype.cancelConfirmMessage = '取消编辑将不保留已经填写的数据,确定继续吗?'; /** * 获取取消编辑时的提示信息内容 * * @return {string} */ FormAction.prototype.getCancelConfirmMessage = function () { return this.cancelConfirmMessage; }; /** * 取消编辑的操作 * * @fires submitcancel * @fires aftercancel */ FormAction.prototype.cancel = function () { var submitCancelEvent = this.fire('submitcancel'); var handleFinishEvent = this.fire('aftercancel'); if (!handleFinishEvent.isDefaultPrevented() && !submitCancelEvent.isDefaultPrevented()) { this.redirectAfterCancel(); } }; /** * 取消编辑时的确认提示 */ FormAction.prototype.cancelEdit = function () { var formData = this.view.getFormData(); if (this.model.isFormDataChanged(formData)) { var options = { title: this.getCancelConfirmTitle(), content: this.getCancelConfirmMessage() }; this.view.waitConfirm(options) .then(u.bind(this.cancel, this)); } else { this.cancel(); } }; /** * 在取消编辑后重定向 * 在有referrer的情况下跳转至referrer * 在没有referrer的情况下history.back() * * 可在业务action里边重写 */ FormAction.prototype.redirectAfterCancel = function () { this.back(this.backLocation, true); }; /** * 提交表单 * * @param {Object} submitData 表单数据 * @return {er.Promise} */ FormAction.prototype.submit = function (submitData) { var handleBeforeSubmit = this.fire('beforesubmit', {submitData: submitData}); if (!handleBeforeSubmit.isDefaultPrevented()) { try { var submitRequester = this.model.submitRequester; return submitRequester(submitData) .then( u.bind(this.handleSubmitResult, this), u.bind(this.handleSubmitError, this) ); } catch (ex) { return Deferred.rejected(ex); } } }; /** * 校验表单前可扩展的操作,在提交之前做*异步*的校验 * 比如弹个框“提交有风险,是否要提交”之类 * * @param {Object} submitData 最终要提交的数据 * @return {*} * 当且仅当返回Deferred.rejected()阻止后续流程 * 其他任意返回结果均与Deferred.resolved()等效 */ FormAction.prototype.beforeValidate = function (submitData) { return true; }; /** * 校验表单后可扩展的动作,在校验之后做*异步*的处理 * 比如弹个框“提交仍有风险,是否要提交”之类 * * @param {Object} submitData 最终要提交的数据 * @return {*} * 当且仅当返回Deferred.rejected()阻止后续流程 * 其他任意返回结果均与Deferred.resolved()等效 */ FormAction.prototype.afterValidate = function (submitData) { return true; }; /** * 进行校验,如果设置了Form的`autoValidate`则先进行表单控件自校验,否则只做自定义校验 * * @param {Object} submitData 最终要提交的数据 * @return {er.Promise} 处理完毕的Promise */ FormAction.prototype.validate = function (submitData) { var localViewValidationResult = this.view.validate(); var localModelValidationResult = this.model.validateSubmitData(submitData); if (localViewValidationResult && localModelValidationResult === true) { return Deferred.resolved(submitData); } if (localModelValidationResult !== true) { this.handleLocalValidationErrors(localModelValidationResult); } this.view.handleValidateInvalid(); return Deferred.rejected(); }; /** * 此处为点击提交按钮后、表单校验前的准备 * 主要逻辑是锁定提交,在校验通过并完成提交操作后释放表单的提交操作 * * 提交流程: * disableSubmit -> * beforeValidate -> * validate -> * afterValidate -> * submit -> * enableSubmit * * 可针对业务需求扩展beforeValidate、afterValidate * validate、submit若与业务有冲突,也可自行修改,但不推荐 */ FormAction.prototype.submitEdit = function () { this.view.disableSubmit(); var formData = this.view.getFormData(); var submitData = this.model.getSubmitData(formData); require('er/Deferred') .when(this.beforeValidate(submitData)) .then(u.bind(this.validate, this, submitData)) .then(u.bind(this.afterValidate, this, submitData)) .then(u.bind(this.submit, this, submitData)) .ensure(u.bind(this.view.enableSubmit, this.view)); }; /** * 初始化交互行为 * * @protected * @override */ FormAction.prototype.initBehavior = function () { BaseAction.prototype.initBehavior.apply(this, arguments); this.view.on('submit', this.submitEdit, this); this.view.on('cancel', this.cancelEdit, this); this.view.on('reset', this.reset, this); }; return FormAction; });