AppML 案例模型
为三个案例写模型:字段定义、校验、默认值与主键。
Key Points模型的写法就是把业务规则翻译成 item 的属性:类型、必填、长度、格式、默认值。
客户模型
XML
<appml>
<datasource>
<query>data/customers.json</query>
</datasource>
<html>
<title>客户管理</title>
</html>
<items>
<item name="id" label="编号" type="number" primarykey="true" readonly="true"/>
<item name="company" label="公司" required="true" maxlength="60"/>
<item name="contact" label="联系人" required="true" maxlength="20"/>
<item name="city" label="城市" default="北京"/>
<item name="credit" label="额度" type="number" min="0" max="1000000" default="0"/>
</items>
</appml>员工模型
XML
<appml>
<datasource>
<query>data/employees.json</query>
</datasource>
<items>
<item name="id" label="工号" type="number" primarykey="true" readonly="true"/>
<item name="name" label="姓名" required="true" maxlength="20"/>
<item name="title" label="职位" required="true"/>
<item name="dept" label="部门" default="技术部"/>
<item name="hiredate" label="入职日期" type="date" required="true"/>
<item name="email" label="邮箱" type="email"
pattern="[^@\s]+@[^@\s]+\.[a-z]{2,}"/>
</items>
</appml>产品模型
XML
<appml>
<datasource>
<query>data/products.json</query>
</datasource>
<items>
<item name="id" label="编号" type="number" primarykey="true" readonly="true"/>
<item name="name" label="名称" required="true" maxlength="80"/>
<item name="category" label="分类" required="true"/>
<item name="price" label="单价" type="number" min="0" step="0.01" required="true"/>
<item name="stock" label="库存" type="number" min="0" default="0"/>
</items>
</appml>属性怎么选
| Business rule | Attribute |
|---|---|
| 不能为空 | required="true" |
| 长度上限 | maxlength="50" |
| 数值范围 | min / max |
| 小数精度 | step="0.01" |
| 格式(邮箱、手机) | pattern="正则" |
| 不可编辑 | readonly="true" |
| 新建时的初始值 | default="..." |
| 唯一标识 | primarykey="true" |
字段命名
XML
<!-- 推荐:与 JSON 的键完全一致,小写,多个词用驼峰或下划线 -->
<item name="hiredate" label="入职日期" type="date"/>
<!-- 不推荐:模型里叫 hire_date,JSON 里叫 hireDate -->name must match the data key character for character, including case. hiredate in the model and hireDate in the data yields a permanently empty column with no error.
pattern is a regular expression; browsers agree on \s and \d but differ in native validation such as <input type="email">. Validate on both sides rather than relying on the frontend alone.校验的边界
JSON
// 前端校验能被绕过:用户可以直接调接口
// 服务端必须再校验一次AppML validation is UX only, not a security boundary. Anyone can remove required in devtools or POST directly. Real constraints must live on the server.
客户模型
XML
<appml>
<datasource>
<query>data/customers.json</query>
</datasource>
<html>
<title>客户管理</title>
</html>
<items>
<item name="id" label="编号" type="number" primarykey="true" readonly="true"/>
<item name="company" label="公司" required="true" maxlength="60"/>
<item name="contact" label="联系人" required="true" maxlength="20"/>
<item name="city" label="城市" default="北京"/>
<item name="credit" label="额度" type="number" min="0" max="1000000" default="0"/>
</items>
</appml>员工模型
XML
<appml>
<datasource>
<query>data/employees.json</query>
</datasource>
<items>
<item name="id" label="工号" type="number" primarykey="true" readonly="true"/>
<item name="name" label="姓名" required="true" maxlength="20"/>
<item name="title" label="职位" required="true"/>
<item name="dept" label="部门" default="技术部"/>
<item name="hiredate" label="入职日期" type="date" required="true"/>
<item name="email" label="邮箱" type="email"
pattern="[^@\s]+@[^@\s]+\.[a-z]{2,}"/>
</items>
</appml>产品模型
XML
<appml>
<datasource>
<query>data/products.json</query>
</datasource>
<items>
<item name="id" label="编号" type="number" primarykey="true" readonly="true"/>
<item name="name" label="名称" required="true" maxlength="80"/>
<item name="category" label="分类" required="true"/>
<item name="price" label="单价" type="number" min="0" step="0.01" required="true"/>
<item name="stock" label="库存" type="number" min="0" default="0"/>
</items>
</appml>属性怎么选
| 业务规则 | 属性 |
|---|---|
| 不能为空 | required="true" |
| 长度上限 | maxlength="50" |
| 数值范围 | min / max |
| 小数精度 | step="0.01" |
| 格式(邮箱、手机) | pattern="正则" |
| 不可编辑 | readonly="true" |
| 新建时的初始值 | default="..." |
| 唯一标识 | primarykey="true" |
字段命名
XML
<!-- 推荐:与 JSON 的键完全一致,小写,多个词用驼峰或下划线 -->
<item name="hiredate" label="入职日期" type="date"/>
<!-- 不推荐:模型里叫 hire_date,JSON 里叫 hireDate -->name 必须与数据里的键逐字相同,包括大小写。模型里写 hiredate、数据里是 hireDate,结果就是「这一列永远是空的」,而且不报任何错误。
pattern 是正则,不同浏览器对正则里 \s、\d 的支持一致,但对 <input type="email"> 这类原生校验的行为不同。跨浏览器场景下建议前后端都再校验一次,不要只依赖前端。校验的边界
JSON
// 前端校验能被绕过:用户可以直接调接口
// 服务端必须再校验一次AppML 的校验只是体验优化,不是安全边界。有人用浏览器开发者工具改掉 required,或者直接 POST 数据,前端校验一点用都没有。真正的约束必须在服务端。