UNPKG

isu-elements

Version:

Polymer components for building web apps.

327 lines (308 loc) 9.45 kB
import { BaseBehavior } from './base-behavior' import { TipBehavior } from './tip-behavior' /** * @polymerBehavior */ const AjaxBehaviorImpl = { /** * GET 请求 * * 例子: *```javascript * 1. 直接传递一个Request 实例 * const req = new Request('/test?foo=1&bar=2', {method: 'GET'}); * this.query(req).then(() => console.log()); * * 2. 直接传递一个url * this.query('/test').then(() => console.log()); * * 3. 直接传递一个包含url、data内容的对象 * this.query({ * url: '/test', * data: { foo:1, bar:2 }, * handleAs: 'json' * }).then(() => console.log()); * ``` * ****************************************************** * * @param {string|Request|Object} input - * 支持3种类型: String|Request|Object * 1. Request实例 * 2. string:请求url * 3: Object: 对象结构要求 { url , data, handleAs} * url:必填项 * apiModule: 可选(api所属服务) * data:可选 * handleAs:string, 可选,默认值是"json", 取值范围: text|json|blob|formData|arrayBuffers * * * @param input * @param loadConfig => default: { showLoading: true, type: 'loading' } * @return {*} */ query (input, loadConfig = { showLoading: true, type: 'loading' }) { let url let apiModule let data = {} let handleAs = 'json' if (Request.prototype.isPrototypeOf(input)) { return this.__fetch(handleAs, input, loadConfig) } else if (Object.prototype.isPrototypeOf(input)) { ({ url = this.throwNotFoundError('url'), data = {}, apiModule = '', handleAs = 'json' } = input) } else { url = String(input) } if (apiModule) { url = `/${apiModule}${url}` } return this.__get(handleAs, { url, data }, loadConfig) }, /** * POST 请求 * * ```javascript * 1. 直接传递一个Request 实例 * const req = new Request('/test?foo=1&bar=2', {method: 'POST'}); * this.post(req).then(() => console.log()); * * 2. 直接传递一个url * this.post('/test').then(() => console.log()); * * 3. 直接传递一个包含url、data内容的对象 * this.post({ * url: '/test', * data: { foo:1, bar:2 } * }).then(() => console.log()); * * 4. 上传文件 * const formData = new FormData(); * formData.append('file1', new File([], 'filename')); * this.post({ * url: '/upload', * data: formData * }).then(() => console.log()); * * 5. 发送json格式的数据 * this.post({ * url: '/upload', * data: {foo:1,bar:2}, * sendAsJson: true * }).then(() => console.log()); * ``` * ****************************************************** * * @param {string|Request|Object} input - * 支持3种类型: String|Request|Object * 1. Request实例 * 2. string:请求url * 3: Object: 对象结构要求 { url , data, handleAs, sendAsJson} * url:必填项 * apiModule: 可选(api所属服务) * data:可选 * handleAs:string, 可选,默认值是"json", 取值范围: text|json|blob|formData|arrayBuffer * sendAsJson:boolean 可选,默认值是false * * @param loadConfig * @return {*} */ post (input, loadConfig = { showLoading: true, type: 'loading' }) { let url let apiModule let data = {} let handleAs = 'json' let sendAsJson = false if (Request.prototype.isPrototypeOf(input)) { return this.__fetch(handleAs, input, loadConfig) } else if (Object.prototype.isPrototypeOf(input)) { ({ url = this.throwNotFoundError('url'), data = {}, handleAs = 'json', apiModule = '', sendAsJson = false } = input) } else { url = String(input) } if (apiModule) { url = `/${apiModule}${url}` } return this.__post(handleAs, { url, data, sendAsJson }, loadConfig) }, /** * DELETE 请求 * * 例子: *```javascript * 1. 直接传递一个Request 实例 * const req = new Request('/test?foo=1&bar=2', {method: 'GET'}); * this.delete(req).then(() => console.log()); * * 2. 直接传递一个url * this.delete('/test').then(() => console.log()); * * 3. 直接传递一个包含url、data内容的对象 * this.delete({ * url: '/test', * data: { foo:1, bar:2 }, * handleAs: 'json' * }).then(() => console.log()); * ``` * ****************************************************** * * @param {string|Request|Object} input - * 支持3种类型: String|Request|Object * 1. Request实例 * 2. string:请求url * 3: Object: 对象结构要求 { url , data, handleAs} * url:必填项 * apiModule: 可选(api所属服务) * data:可选 * handleAs:string, 可选,默认值是"json", 取值范围: text|json|blob|formData|arrayBuffers * * @param loadConfig => default: { showLoading: true, type: 'loading' } * @return */ delete (input, loadConfig = { showLoading: true, type: 'loading' }) { let url let apiModule let data = {} let handleAs = 'json' if (Request.prototype.isPrototypeOf(input)) { return this.__fetch(handleAs, input, loadConfig) } else if (Object.prototype.isPrototypeOf(input)) { ({ url = this.throwNotFoundError('url'), apiModule = '', data = {}, handleAs = 'json' } = input) } else { url = String(input) } if (apiModule) { url = `/${apiModule}${url}` } return this.__delete(handleAs, { url, data }, loadConfig) }, __get (handleAs, { url, data }, loadConfig) { const reqUrl = new URL(window.location.origin + url) Object.keys(data).filter(key => data[key] != undefined).forEach((key) => reqUrl.searchParams.append(key, data[key])) const req = new Request(reqUrl, { method: 'GET', credentials: 'include' }) return this.__fetch(handleAs, req, loadConfig) }, __post (handleAs, { url, data, sendAsJson }, loadConfig) { let body, headers if (sendAsJson) { headers = { 'content-type': 'application/json;charset=utf-8' } body = JSON.stringify(data) } else if (data instanceof FormData) { body = data } else { const searchParams = new URLSearchParams() Object.keys(data).forEach((key) => searchParams.append(key, data[key])) body = searchParams } const req = new Request(url, { method: 'POST', credentials: 'include', headers, body }) return this.__fetch(handleAs, req, loadConfig) }, __delete (handleAs, { url, data }, loadConfig) { const reqUrl = new URL(window.location.origin + url) Object.keys(data).filter(key => data[key] != undefined).forEach((key) => reqUrl.searchParams.append(key, data[key])) const req = new Request(reqUrl, { method: 'DELETE', credentials: 'include' }) return this.__fetch(handleAs, req, loadConfig) }, /** * * loadConfig = { showLoading: true, type: 'nprogress' } * 参数介绍: showLoading @type {boolean} @default false * type @type string @default `loading` , value: `loading`|`nprogress`, if value !== `nprogress`, value === `loading` * * @param handleAs * @param request * @param loadConfig => default: { showLoading: true, type: 'loading' } * @private */ async __fetch (handleAs, request, loadConfig = { showLoading: true, type: 'loading' }) { try { if (window.__mockEnabled && typeof MockDataPool !== 'undefined') { const matchedRes = MockDataPool.match(request) if (matchedRes) { const response = new Response(matchedRes.body, matchedRes) return Promise.resolve(response).then(res => res.json()) } } this.showLoadingByStatus(loadConfig) const response = await window.fetch(request) this.hideLoadingByStatus(loadConfig) if (response.ok) { if (response.headers.has('Content-length') && Number(response.headers.get('Content-length')) === 0) { return Promise.resolve() } else { return response[handleAs]() } } else { const err = await response.text() throw err } } catch (e) { this.hideLoadingByStatus(loadConfig) this.isuTip.error(e) return await Promise.reject(e) } }, /** * 根据参数设置隐藏loading的方式 */ hideLoadingByStatus ({ showLoading, type }) { if (!showLoading) return switch (type) { case 'loading': this.hideLoading() break case 'nprogress': this.hideNprogress() break default: this.hideLoading() break } }, /** * 根据参数设置显示loading的方式 */ showLoadingByStatus ({ showLoading, type }) { if (!showLoading) return switch (type) { case 'loading': this.showLoading() break case 'nprogress': this.showNprogress() break default: this.showLoading() break } } } export const AjaxBehavior = [BaseBehavior, TipBehavior, AjaxBehaviorImpl]