Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从 Validation 结果的 message 里面去掉 field 的部分 #12

Merged
merged 1 commit into from Sep 21, 2015

Conversation

huacnlee
Copy link
Contributor

原因:

如果你尝试 I18n 处理 Validation message 的时候,你会发现,你必须也只能写成这样:

因为我们覆盖 validation.translate 函数的时候,无法知道传过来的参数是什么类型,只能一起处理了

errors:
  "%s required": '%s 是必填项"
  "name": "姓名"
  "age": "年龄"

比如是这样的实现:

validate.translate = function() {
  return I18n.t('errors.' + args[0]);
};

但实际的项目设计中,我们一般会按类别才分 I18n 信息,类似这样:

model:
  user:
    name: "姓名"
    age: "年龄"
  category:
    name: "分类名称"
  errors:
     "required": "是必填项"
validate.translate = function() {
  return I18n.t('model.errors.' + args[0]);
};

而缺少的 field 信息,可以另外处理,做拼接在显示在界面上。

@hotoo
Copy link
Member

hotoo commented Sep 18, 2015

@fengmk2
Copy link
Member

fengmk2 commented Sep 18, 2015

@hotoo 你来负责 review 和合并

@fengmk2
Copy link
Member

fengmk2 commented Sep 18, 2015

也给你 npm owner 了

npm owner add hotoo parameter
+ hotoo (parameter)

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

@huacnlee

  1. validate.translate 建议不要了。应用中直接 err.field + I18n.t('model.errors.' + err.message)
  2. rebase 合并下 commit

@huacnlee
Copy link
Contributor Author

@hotoo I18n.t 是我假设的呀,这里根本就没这个函数

另外,已经 rebase 过的,现在是可以直接合并的状态

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

我的意思是:应用可以使用任意本地化方案。不需要 parameter 提供 validate.translate 方法来支持。

比如用 koa-locales:

err.field + __('model.errors.' + err.message)

应用使用任意本地化方案都可以自己做,不用 paramter 掺和。

@huacnlee
Copy link
Contributor Author

1. 此 PR 解决的是 message 里面带有 key 会造成无法转换语言的问题,不管是不是暴露函数的做法都有这个问题;
2. koa-locales 无法直接引进来,他需要依赖 Content,而 parameter 是和 HTTP 上下文无关的库;
3. 就算 koa-locales 能解决问题,这里也不能定义 model.errors.xxx,因为 parameter 不是 model,这么命名欠妥,顶多能叫 parameter.errors.xxx

所以一开是我没提交直接在 parameter 里面内置 locales 信息原因就是上面。我也希望在 parameter 内部直接实现 I18n 翻译,这样也不用这么复杂的绕了一大圈。但首先得有一个 I18n 库引进来。

抱歉,前面一句回复我看错了,你说的时应用里面可以那么用。

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

定义 model.errors.xxx 还是其他什么,是应用的事情,不关 parameter 什么事。

parameter 提供了 err.code, err.field, err.message(without key/field) 这些已经够。应用要怎么用(比如本地化)是应用的事。

  • 本地化方案是应用自己选的。
  • 方言是应用自己定义的。

所以 parameter 不用提供 translate 方法。

@huacnlee
Copy link
Contributor Author

如果没有这些可变值,或许还可以去掉那个函数

https://github.com/node-modules/parameter/blob/master/index.js#L378
https://github.com/node-modules/parameter/blob/master/index.js#L338

'should be one of %s', rule.values.join(', ')

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

这个确实有点小麻烦,不过即便这样,tranlate 方法也没有解决这个问题。

对于应用来说,rule.compare 一般是比较固定、明确的,方言中定义好这些明确的 key/field 就好了。

@huacnlee
Copy link
Contributor Author

有解决啊

verify.translate = function() {
  let args = Array.prototype.slice.call(arguments);
  args[0] = `form.errors.${args[0]}`;
  return ctx.__.apply(ctx, args);
};
t('should be one of %s', rule.values.join(', '))

=> '要求在 [1,2,3] 其中一个'

目的是要翻译错误信息,而不是后面的 %s 的内容, %s 的内容原样输出就好了。

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

  • args 好晦涩。
  • 在 App 中:
const errors = validate(rule, data);
errors.forEach(function(err) {
  const msg = ctx.__('form.errors.' + err.message);
  // do you want.
});

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

应用自己本地化就好了哇,为什么一定要传个本地化方法给 parameter,让 parameter 给你执行下。

@huacnlee
Copy link
Contributor Author

name limit 10
password limit 30
nick limit 20

然后我就得写 3 段一模一样的话

length should smaller than 10
length should smaller than 20
length should smaller than 30

本来只需要写一遍的:

form: {
  errors: {
    'missing_field': '缺少必要字段',
    'invalid': '无效格式',
    'required': '要求是必填字段',
    'should be an integer': '要求是数字',
    'should be an email': '要求是 Email 格式',
    'should not be empty': '不能为空',
    'should be a string': '要求是字符串',
    'should match %s': '要求匹配格式 %s',
    'should equal to %s': '要求等于 %s',
    'should be a url': '要求是一个 URL 地址',
    'should be an object': '要求是一个对象',
    'should be an array': '要求是一个数组',
    'should be a boolean': '要求是 true 或 false',
    'should be one of %s': '要求是 %s 其中的一个',
    'length should smaller than %s': '长度要求小于 %s',
    'length should bigger than %s': '长度要求大于 %s'
  }
}

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

合并下 commit 吧,先合掉。

这个本地化方案我觉得需要好好设计下。

@fengmk2
Copy link
Member

fengmk2 commented Sep 21, 2015

哈哈,终于看到开源项目级别的 review 了!

@huacnlee
Copy link
Contributor Author

为何需要固定翻译!!!这个真的很重要

比如目前我实现这个功能是为了让一个框架提供默认的验证功能,这是基于 parameter 做了一层封装,而框架已经提供了默认的 I18n 功能,开发者无需配置任何本地化信息,至少在验证信息的本地化文本是不需要配置的。

于是框架默认带了:

form: {
  errors: {
    'missing_field': '缺少必要字段',
    'invalid': '无效格式',
    'required': '要求是必填字段',
    'should be an integer': '要求是数字',
    'should be an email': '要求是 Email 格式',
    'should not be empty': '不能为空',
    'should be a string': '要求是字符串',
    'should match %s': '要求匹配格式 %s',
    'should equal to %s': '要求等于 %s',
    'should be a url': '要求是一个 URL 地址',
    'should be an object': '要求是一个对象',
    'should be an array': '要求是一个数组',
    'should be a boolean': '要求是 true 或 false',
    'should be one of %s': '要求是 %s 其中的一个',
    'length should smaller than %s': '长度要求小于 %s',
    'length should bigger than %s': '长度要求大于 %s',
  }
}

如果想 @hotoo 那样直接把 message 抛出来,里面包含 %s 的实际内容,那这个时候框架就无法提供默认的翻译信息了,因为 %s 的内容是由框架的使用者定义的。

而 validate.translate 提供了一个可以操控的途径。

当然这不是最佳方案。
但目前也没有其他好的方案了,至少是我目前想到的最好方案。


还有一个做法是 parameter 直接引入 I18n 方案,内部转换掉,但使用者想要修改文案的时候就困难了。

@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

嗯,我的意思也是感觉现在的方案有点蹩脚,这个问题先放着。

合并下 commit 我合并 PR

fix: Email, Url message has translate twice.
hotoo added a commit that referenced this pull request Sep 21, 2015
从 Validation 结果的 message 里面去掉 field 的部分
@hotoo hotoo merged commit 4f78c68 into master Sep 21, 2015
@hotoo hotoo deleted the validate-message-remove-key branch September 21, 2015 03:57
@hotoo
Copy link
Member

hotoo commented Sep 21, 2015

不兼容修改,1.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants