我需要将模型的名称字段设置为虚拟,通过将两个真实字段连接在一起来创建。此名称仅供显示。我已经尝试过doc中的虚拟示例,没有运气。 Keystone 4 beta5。
var keystone = require('keystone')
_ = require('underscore');
var Types = keystone.Field.Types;
/**
* Foo Model
* ==================
*/
var Foo = new keystone.List('Foo', {
map: {name: 'fooname'},
track: true
});
Foo.add({
bar: { type: Types.Relationship, required: true, initial: true, label: 'Barref', ref: 'Bar', many: false },
order: { type: Types.Select, required: true, initial: true, label: 'Order', options: _.range(1,100) },
price: { type: Types.Money, format: '$0,0.00', label: 'Price', required: true, initial: true },
});
Foo.schema.virtual('fooname').get(function() {
return this.bar+ ' ' + this.order;
});
Foo.defaultColumns = 'fooname, bar, order, price';
Foo.register();
当我使用此模型定义时,我在defaultcolumns列表中看不到虚拟名称。我想创建一个虚拟名称,以便在将此模型用作关系时查找更容易。
答案 0 :(得分:1)
您不需要虚拟来执行此操作。 Keystone允许您在每次保存文档时跟踪和重新计算字段。您可以启用这些选项,以便创建一个为您连接这两个值的函数(同步或异步,您的选择。)
我注意到的另一件事是bar
是Relationship
,这意味着您需要在从中获取任何有用信息之前填充该关系。这也意味着你的value
函数必须是异步的,这就像将回调函数作为参数传递给该函数一样简单。 Keystone完成剩下的工作。如果您不需要此bar
中的任何信息,并且只需要_id
(模型始终具有),则可以不使用我包含的keystone.list('Bar')
函数。< / p>
http://keystonejs.com/docs/database/#fields-watching
map
对象也指模型上的一个选项,因此在任何情况下您都需要在模型上使用fooname
属性,尽管它是动态计算的。
var keystone = require('keystone'),
_ = require('underscore');
var Types = keystone.Field.Types;
/**
* Foo Model
* ==================
*/
var Foo = new keystone.List('Foo', {
map: {name: 'fooname'},
track: true
});
Foo.add({
fooname: { type: Types.Text, watch: true, value: function (cb) {
// Use this if the "bar" that this document refers to has some information that is relevant to the naming of this document.
keystone.list('Bar').model.findOne({_id: this.bar.toString()}).exec(function (err, result) {
if (!err && result) {
// Result now has all the information of the current "bar"
// If you just need the _id of the "bar", and don't need any information from it, uncomment the code underneath the closure of the "keystone.list('Bar')" function.
return cb(this.bar.name + " " + this.order);
}
});
// Use this if you don't need anything out of the "bar" that this document refers to, just its _id.
// return cb(this.bar.toString() + " " + this.order);
} },
bar: { type: Types.Relationship, required: true, initial: true, label: 'Barref', ref: 'Bar', many: false },
order: { type: Types.Select, required: true, initial: true, label: 'Order', options: _.range(1,100) },
price: { type: Types.Money, format: '$0,0.00', label: 'Price', required: true, initial: true },
});
Foo.defaultColumns = 'fooname, bar, order, price';
Foo.register();
答案 1 :(得分:-1)
您能提供更多信息吗?什么是目前的工作?它应该如何工作? 示例代码?
编辑:
创建模型Foo
后,您可以使用属性Foo.schema
访问Mongoose模式。 (Keystone Concepts)
这个schema
为所有注册了钩子的方法提供了pre
- 钩子。 (Mongoose API Schema#pre)
其中一种方法是save
,可以像这样使用:
Foo.schema.pre('save', function(next){
console.log('pre-save');
next();
});
答案 2 :(得分:-1)
试试这个:
Foo.schema.pre('save', function (next) {
this.name = this.bar+ ' '+ this.order;
next();
});