2017-02-28 74 views
1

我需要通过将两个实际字段连接在一起来创建模型的名称字段为虚拟。此名称仅用于显示。我已经尝试了文档中的虚拟示例,但没有运气。 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列表中看不到虚拟名称。我想创建一个虚拟名称,以便在将此模型用作关系时查找更容易。

回答

-1

您能否提供更多信息?什么是目前的工作?它应该如何工作? 示例代码?

编辑:

创建模型Foo后,您可以访问使用属性Foo.schema猫鼬架构。 (Keystone Concepts

这个schema提供了一个pre钩 - 所有的方法,其中挂钩。 (Mongoose API Schema#pre

其中的一个方法是save,它可以这样使用:

Foo.schema.pre('save', function(next){ 
    console.log('pre-save'); 
    next(); 
}); 
+0

编辑初始文章添加代码示例模型和更多的解释。 thx –

-1

试试这个:

Foo.schema.pre('save', function (next) { 
    this.name = this.bar+ ' '+ this.order; 
    next(); 
}); 
+1

尽管这可能会解决作者的问题,但仅有代码的答案对实际学习没有多大帮助。你可能会解释为什么这是答案。 –

0

你并不需要一个虚拟的做到这一点。每次保存文档时,Keystone允许您跟踪和重新计算字段。您可以启用这些选项以创建一个函数,将这两个值连接起来(同步或异步,您的选择)。

我注意到的另一件事是barRelationship,这意味着您需要在获得任何有用的信息之前填充该关系。这也意味着您的value函数必须是异步的,这与将回调函数作为参数传递给该函数一样简单。其他的是Keystone。如果您不需要此bar中的任何信息,并且您只需要_id(该模型始终具有),则可以不使用我包含的keystone.list('Bar')函数。

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();