Giter Site home page Giter Site logo

bat-ria's Introduction

BAT-RIA 扩展

额外依赖的 edp 包

  • urijs

ESL config

启动入口

common/main(或其他入口模块)中如此通过 BAT-RIA 来启动系统:

require('bat-ria/main').start(config).then(function () {
    // custom system initialization
});

bat-ria/main 会请求用户、常量数据后启动 ER,完成后可以进行额外的系统初始化(导航栏、用户信息区域的渲染等)。

用户信息和常量接口

bat-ria/main 负责请求后端用户和系统常量接口数据。

两个接口的 URL 需要在 common/config 模块下的 api.userapi.constants 中进行配置。

用户数据接口有如下两种情况:

  1. 对于可能以他人身份登录系统的情况,result 需要符合如下格式:

    {
        visitor: {
            // 当前登录用户自身信息
        },
    
        adOwner: {
            // 被登录的广告主的信息
        }
    }
  2. 只会有一种身份登录的系统,直接在 result 中展开用户信息字段即可(非 1. 中所述情况时自动视作此情况)。

读取完毕后,会在下面两个模块封装对应的数据:

  • bat-ria/system/user
  • bat-ria/system/constants

user.visitor 提供正在访问系统的用户的信息,user.ader 用来在管理员以他人身份登录系统时提供被登录用户的信息(可能不存在)。

util

常用的单纯的数据操作工具被扩展到了 underscore 中,参见 bat-ria/extension/underscore。 其他和 ER/ESUI/EF 相关的辅助方法在 bat-ria/util 中。

bat-ria's People

Contributors

chestnutchen avatar justineo avatar leeight avatar markfan avatar miyakosama avatar osdream avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bat-ria's Issues

在线等,自定义ui且不在官方ui目录下,如何解决依赖路径查找问题

需求:由于自己挖的坑(#70),data-ui-type和data-ui="type:xxx"都已经升级成支持主动提取ui依赖,那么我如果有自己定义的ui且不放在官方ui目录下怎么搞?(以前我用data-ui的写法来引用自定义的ui,用data-ui-type来引用官方ui)

我看bat-ria/tpl.js 里面有个registerControl,看了下注释,这是用来注册自定义不在esui目录下的控件。
有两个问题

  • 这个方法在什么地方调用,感觉在xxxView文件最合理,但是这时候tpl因为语法已经被提前require且自动依赖解析了需要的ui,这时候还没有执行register导致自定义ui找不到
define(function (require) {
    // require template
    require('bat-ria/tpl!./list.tpl.html');
    var ListView = require('bat-ria/mvc/ListView');
    var tpl = require('bat-ria/tpl');
    tpl.registerControl('commom/MyUI');
  • 从registerControl的实现来看,控件名字貌似不能重复,有啥最佳实践规范保证不冲突不?

支持edpx-bat-ria

已经有了edpx-ub-ria了,这样子直接可以用过edp ub-ria来调用了,所以bat-ria也需要搞一搞。

List提交查询参数时,当redirectAfterChange为true时即全局刷新,没有过滤查询参数

RT。是不是跟局部刷新一样,也加上过滤查询参数较好?
关键代码点这里

现在我有个使用场景就涉及到这个问题了:
我的查询操作里有一级行业和二级行业,当点击查询按钮时,行业参数中使用新的参数名,当选择二级行业选择值时行业参数使用二级行业值,当选择二级行业全部行业选项时行业参数使用一级行业值。
如图:
image

框架支持RESTFUL风格的接口

现在框架里面的API都需要通过提前定义而且只支持get和post的方法,如何支持put和delete以及动态路由呢?

RichBoxGroup 功能

  • 支持 HTML 内容并渲染内部控件
  • 选择变化切换对应状态的 class
  • 多选时支持「最多选择 max 项,选满后禁用其它项」(注意 maxvaluerepaint 也要更新)

extension/ui.js的疑似bug

4个Rule:MaxRule/MinRule/MaxLengthRule/MinLengthRule
的prototype.getErrorMessage,第一行都是control.get('maxErrorMessage')
这个maxErrorMessage是否是copy手误?

另外4个getErrorMessage比较一致,是否可以抽取成一个,比如:
MaxRule.prototype.getErrorMessage = someMethod(control, 'maxErrorMessage');
MinRule.prototype.getErrorMessage = someMethod(control, 'minErrorMessage');
someMethod里面会return一个function。

函数内:
var getErrorMessage = Rule.prototype.getErrorMessage;
getErrorMessage.apply(this, arguments);
这个apply出来的,并没有赋给局部变量...是否可以存下来,最后一行return的时候,return此变量即可

主导航模块

需要增加一个 navigator 模块,支持配置 Action path 和导航 Tab 的对应关系,并且在重定向或点击 Tab 时同步当前所在模块的显示。

FormAction中getToastMessage方法有bug

当需要自定义toastMessage时,getToastMessage方法在解析toastMessage后返回的是一个函数(u.template函数执行结果是一个函数),导致最终显示的是function() {}....这儿样的。代码如下:

exports.getToastMessage = function (result) {
        var message = this.toastMessage;
        if (message == null) {
            return '';
        }

        if (message) {
            return u.template(message, result || {}); // 这里返回的是函数
        }
        else {
            return '保存成功';
        }
    };

业务系统常用命名规范(草案)

我们先内部讨论一下:


词汇表

API 说明文档应该在开头部分对业务相关的词汇进行约定,给出一份供所有人参考的词汇表。

可以参考商业阿拉丁资源库接口文档的相应部分


通用命名

为了避免不同产品线对业务对象的增删改查等操作都使用不同词汇从而增加了沟通和维护的成本,在此对接口、Action路径中的常用操作和展现形式的语义进行明确,对类似含义的词汇进行合并。

常用操作

create
系统中不存在,从无到有进行创建。
add ← attach
将已有的东西关联到其他东西上(add A to B)。
remove
将已有的东西从其他东西上移除但仍存在于系统中,即去除关联关系(remove A from B)。
delete ← destroy
从系统中彻底删除一个东西,使其不存在。
modify ← edit / change
对业务对象进行修改。
update
使修改生效(持久化)。
save
保存修改后的内容,但不实际生效(一般业务中对应「仅保存」的情况)。
submit
通用的提交操作(比如 create / update 共用,通过 id 参数是否存在来判断类型等)。

常用展现形式

对于查询类的操作,我们可以通过下面的方式来描述被查看内容的展现形式:

list
以列表方式展现。
detail
以详情方式展现。
summary
以概要方式展现。
chart
以图表方式展现。

Action 命名

模块名 → 业务对象 → 修饰符 → 操作 / 展现方式

[/<module>]+/<entity>[/[<modifier>||<entity>]]*/[<operation>||<display>]

eg.

  • /promotion/ad/list
  • /promotion/material/daily/list
  • /validation/enterprise_qualification/create
  • /account/setting/modify // 前端的修改入口,用 modify 比较合适

前后端接口命名

统一前缀 → 模块名 → 业务对象 → 修饰符 → 操作 / 展现方式

/data[/<module>]+/<entity>[/[<modifier>||<entity>]]*/[<operation>||<display>]

注:前后端接口中的 ad 字样统一用 1730xAD === 173)代替,以免请求被 AdBlock 等工具过滤。

eg.

  • /data/promotion/173/update // 将修改提交到后端,统一用 update
  • /data/promotion/173/pie/chart // 推广计划的饼图数据
  • /data/promotion/material/daily/list // 将物料信息按天统计成列表
  • /data/promotion/material/save // 仅保存物料
  • /data/validation/enterprise_qualification/create

剥离业务相关的逻辑

把业务相关的东西都移到具体项目里去,之后提供工具来生成。

  • extension 中的 hooks
  • mainsession / constants 相关的接口需要抽象
  • system/user

验证错误信息的展示

目前,在展示验证错误信息的时候,会取指定名字的一组控件的第一个控件显示验证错误信息。比如,有5个 TextBox 控件,名字都叫 names ,验证规则是不能存在两个相同的值,如果第一个 TextBox 和第二个 TextBox 都输入了zhangsan ,那么就会触发验证错误,然后错误会显示在第一个 TextBox 控件下面,后面控件不会变成出错的状态,参见此处代码

目前期望尽量能做到在视觉上的最后一个控件旁边显示错误信息,值重复的两个 TextBox 边框飘红。

另外,对于 readonly 、 hidden 和 disabled 的控件是否需要不理会出错状态, @Justineo 大神在 JS Bin 上做了测试,原生的 input 对 readonly 和 disabled 是不会去设置验证不通过状态的,此处是具体示例

Upload功能增强评审

Uploader功能增强

  1. 支持在url中传递参数,将callback放到url里边去,保证后端解析multipart出错的情况下也能拿到callback

  2. 增加readonlydisable方法和状态、样式

  3. 各种中间状态可配置(可去除正在上传、上传完成等中间状态及样式)

  4. 增加撤销当前文件功能,包括置空input内容,清空Uploader对象缓存内容及状态

  5. 对后端返回的结构体增加content,type,width,height的提取

    /* success */
    {
        "success": true,
        "message": {},
        "result": {
            "previewUrl": "http://",
            "url": "http://",
            "content": "宝马,宝马新车,宝马旧车",
            "type": "auto|image|falsh",
            "width": 100,
            "height": 100
        }
    }
    
    /* failed */
    {
        "success": false,
        "message": "含有非法字符/不正确的文件类型/宽度超出限制/高度超出限制/文件大小超出限制/其他出错信息"
    }
  6. 增加extraArgsrepaint

ui/navigator 不能添加图标

我遇到了这样一个需求: 给导航栏添加图标,但是config中没有配置图标的功能。我查看源码发现由于navigator对text的值进行了escape的转义,没办法通过 text: "<i class="icon"></i> 首页" 的形式给导航添加图标,具体源代码如下:

                element.innerHTML = '<a href="' + url + '"' + target + '>'
                                        + '<span>' + u.escape(item.text) + '</span>'
                                    + '</a>';

我觉得这里没必要进行转义,去掉反而可以留给开发更大的空间,谢谢!

优化 ListAction 的模板

需要用 ETpl 3.0 的带入引用功能重写模板,方便局部定制(包括脚手架生成的默认模板)。

PassportBinder 控件

企业百科目前实现的账户绑定有些问题,需考虑按贴吧推广之前用过的方式来做。

mockup的优化

关于mockup常用路由规则及handler进bat-ria和结构优化的讨论


背景,mockup目前已有的功能

  1. json数据返回模拟(如需random的数据要自己实现)
  2. 上传文件模拟
  3. 延迟功能
  4. 代理模式(转发至rd机器)

mockup常用路由规则及handler进bat-ria

目前项目中的mockup的路由规则及handler都是直接堆在edp-websever-config.js中,代码较长,路由规则难找。如图所示。
qq20140325-3
考虑到业务端的常用路由规则及handler的重用,计划整理一份公用handler到bat-ria中,之后通过脚手架生成一份常用的edp-websever-config.js

目的

代码重用,保持edp-websever-config.js清晰可读,业务端可在常用版本上自行扩展。

大概的用法如下:

{
    location: require('dep/ecma/locationAndHandler').uploadLocation,
    handler: require('dep/ecma/locationAndHandler').uploadHandler
}

各业务端可根据业务需求修改location或使用其他handler。

目前已有的规则及handler

  1. 路由规则/^\/data\//及其handler,视为返回json的普通接口
  2. 路由规则/^\/data.+upload$/及其handler,视为上传文件的接口,返回html
  3. 路由规则referred是否有ed或enable_debug,无ed默认转发至rd机器,有ed视为本地调试

还可以有的规则

  1. 路由规则jsonp

mockup目录结构优化

目前项目中mockup的结构是与后端接口对应的,举个栗子

/data/bk/validation/delete(我是一个普通的删除接口)

对应的mockup目录结构为

mockup/data/bk/validation/delete.js

目录层级居然有4层,创建到手疼。因此希望直接在mockup目录下有个mockup.js,路径的映射放到mockup.js里边做,不要依赖目录结构。

再举个栗子

/data/bk/personInfo/submit (我是一个不需要返回任何result的接口)

上边两个接口的mockup是这样的

exports.response = function (path, params) {
    return {
        "success": "true",
        "message": {},
        "result": {
        }
    };
}

这两个文件是一模一样的,但是由于还没有公用的方法,暂时只能copy & paste一次

目的

减少mock一个接口的工作量,一个接口可以重用同一个json串返回

可以优化的事情

  1. 去除目录结构依赖,路径映射放到js里边做
  2. 公共返回的json串
  3. 更加聪明的mockup,添加常用的random数据

RichTextInput 控件

锦囊等系统中均有封装(基于 UEditor),ESUI 3 版本的控件也可考虑封装一下。

ListAction redirect的问题

ListAction对url参数有依赖,但是在ListAction作为childAction的时候,无法修改parent的url,需要在redirect的时候把修改后的url通过事件抛出来。

bat-ria/tpl支持加载amd格式的模板文件

--- a/dep/bat-ria/0.1.7/src/tpl.js
+++ b/dep/bat-ria/0.1.7/src/tpl.js
@@ -156,13 +156,18 @@ define(
                     require(dependencies, function () { load(text); });
                 }

-                var options = {
-                    method: 'GET',
-                    url: parentRequire.toUrl(resourceId),
-                    cache: true,
-                    dataType: 'text'
-                };
-                ajax.request(options).then(addTemplate);
+                if ( /html?/.test( resourceId ) ) {
+                    var options = {
+                        method: 'GET',
+                        url: parentRequire.toUrl(resourceId),
+                        cache: true,
+                        dataType: 'text'
+                    };
+                    ajax.request(options).then(addTemplate);
+                }
+                else {
+                    require( [ resourceId ], addTemplate );
+                }

获取当前已选择的数据getSelectedTree为啥不遍历子节点的数据

/**
         * 或许当前已选择的数据
         *
         * @return {Object}
         * @public
         */
        TreeRichSelector.prototype.getSelectedTree = function () {
            var me = this;
            var copyData = u.deepClone(this.allData);
            var nodes = copyData.children;
            u.each(nodes, function (node) {
                var selectedChildren = getSelectedNodesUnder(node, me);
                if (selectedChildren.length) {
                    node.children = selectedChildren;
                }
                else {
                    node.children = null;
                }
            });
            var filteredNodes = u.filter(nodes, function (node) {
                return node.children;
            });
            copyData.children = filteredNodes;
            return copyData;
        };

        function getSelectedNodesUnder(parentNode, control) {
            var children = parentNode.children;
            var indexData = control.indexData;
            return u.filter(children, function (node) {
                var indexItem = indexData[node.id];
                return indexItem.isSelected;
            });

        }

看上面的函数getSelectedTree和getSelectedNodesUnder都只是找了一层,为啥不遍历子节点接着查找啊?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.