使用“get”应该是有问题的.model-builder.js中的方法
Something should be wrong with applying of "getter" methods in model-builder.js
我正在尝试设置一些基本场景,并使用环回来了解其实际的灵活性和可用性水平。
其中之一是在处理数据库(例如MySQL)的源数据时,必须修改结果JSON对象中的某些属性的值。
我使用以下版本:
strong-cli v2.5.5 (node v0.10.29)node-inspector v0.7.4建军筑v0.1.0strong-cluster-control v0.4.0strong-registry v1.1.0Strong-supervisor v0.2.3 (strong-agent v0.4.9, strong-cluster-control v0.4.0)loopback-datasource-juggler v1.6.2loopback-connector-mysql v1.4.1
我尝试了所有方法,但看起来"getter"方法是通过我不理解的方式应用的,或者有一个错误。
为了描述这个问题,我使用了一个简单的表"city"(在MySQL数据库中):
CREATE TABLE `city` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`countryId` bigint(20) NOT NULL,
`name` varchar(100) NOT NULL,
`comment` varchar(255) DEFAULT NULL,
`enabled` char(1) NOT NULL DEFAULT 'Y',
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
)
和填充一些简单的数据。
为了在环回中定义模型,我使用了位于"models"目录下的"city.js"文件:
"use strict";
var loopback = require('loopback');
var app = require('../app.js');
var properties = {
id: {type: "number", id: true},
countryId: {type: "number"},
name: {type: "string"},
comment: {type: "string"},
enabled: {type: "string"}
};
var options = {
acls: [
{
accessType: "*",
permission: "ALLOW",
principalType: "ROLE",
principalId: "$everyone"
}
]
};
var City = app.model("city", {
properties: properties,
options: options,
public: true,
dataSource: "mysql",
plural: "cities"
});
City.getter["enabled"] = function(v) {
console.log("Getter is called: ", v);
return 'Q'
};
正如你所看到的,"getter"方法是在"city"模型上使用"city"对象定义的。
当我尝试运行环回,然后通过StrongLoop API浏览器发送请求:
http://localhost:3000/api/cities/1
控制台看起来像(包括DEBUG=loopback:connector:*的信息):
supervisor running without clustering (unsupervised)
loopback:connector:mysql Settings: {"connector":"loopback-connector-mysql","host":...
connect.multipart() will be removed in connect 3.0
visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives
connect.limit() will be removed in connect 3.0
Getter is called: undefined
Getter is called: undefined
2014-07-12T12:26:41.978Z pid:12180 worker:supervisor INFO strong-agent not profiling, ...
2014-07-12T12:26:41.981Z pid:12180 worker:supervisor Generate configuration with:
2014-07-12T12:26:41.983Z pid:12180 worker:supervisor npm install -g strong-cli
2014-07-12T12:26:41.983Z pid:12180 worker:supervisor slc strongops
2014-07-12T12:26:41.983Z pid:12180 worker:supervisor See http://docs.strongloop.com/...
Browse your REST API at ...
LoopBack server listening @ ...
Getter is called: undefined
loopback:connector:mysql SQL: SELECT * FROM `city` WHERE `id` = 1 LIMIT 1 +8s
loopback:connector:mysql Data: +9ms [ { id: 1,
countryId: 1,
name: 'Brno',
comment: 'The second largest city of its country',
enabled: 'Y' } ]
Getter is called: undefined
GET /api/cities/1 304 44ms
,结果如下:
{
"id": 1,
"countryId": 1,
"name": "Brno",
"comment": "The second largest city of its country",
"enabled": "Q"
}
正如你所看到的,"enabled"属性最终被"getter"方法改变了,但是:
- ` getter `方法在初始化环 时也被称为2x
- 'getter'方法也在查询MySQL数据库之前立即调用1x
- console.log(v)内部'getter'方法总是返回'undefined'
loop -datasource-juggler中'model-builder.js'的源代码(第364行)
Object.defineProperty(ModelClass.prototype, propertyName, {
get: function () {
if (ModelClass.getter[propertyName]) {
return ModelClass.getter[propertyName].call(this); // Try getter first
} else {
return this.__data && this.__data[propertyName]; // Try __data
}
},
是一个解释。'call'方法只有一个参数(this),表示被调用函数中的'this'对象,没有第二个参数表示被调用函数中的'v'参数(与Raymond Feng关于如何创建getter和setter重写的回答有关)。
问题还在于'getter'方法中的'this'总是表示一个包含模型所有属性的对象:
City.getter["enabled"] = function(v) {
console.log("Getter is called: ", this);
return 'Q'
};
和来自控制台的消息:
Getter is called: { id: 1, countryId: 1, name: 'Brno', comment: 'The second largest city of its country', enabled: 'Y' }
你能给我解释一下"getter"方法当前的实现思路吗?
谢谢你。
米洛斯岛青金石多层陶瓷
更新非常感谢Raymond的回答。
一开始我是这么想的,但是当我用了这样的东西:
City.getter["enabled"] = function() {
return this.enabled + "x"
};
节点立即崩溃当我请求:
localhost:3000/api/cities/1
RangeError: Maximum call stack size exceeded
这就是为什么我认为你的实现有点不同。有什么问题吗?
我到底应该用什么来添加'x'到从db检索的实际值?
谢谢。
米洛斯岛青金石多层陶瓷
在您的示例代码中,您正在递归地调用您定义的getter。
City.getter["enabled"] = function() {
// this.enabled calls City.getter["enabled"]
return this.enabled + "x"
};
从DB检索到的值存储在__data
属性中。下面是更正后的getter函数:
City.getter["enabled"] = function() {
return this.__data.enabled + "x"
};
JavaScript getter函数的格式如下:
function() {
// this is the object instance owning the property
}
请注意getter函数不带任何参数,接收者是拥有该属性的对象实例。例如:
myModelInstance。myProperty将调用getter函数,并将其设置为myModelInstance。详见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
- mongoose.js Model.remove在循环中只能工作一次
- vue-js-单选按钮won't默认情况下使用v-model属性进行检查
- Cufon-builder-font-js文件在Fabric.js中不起作用
- 从node.js应用程序调用Mongoose Model.save()时挂起
- vue.js,主el之外的v-model
- 未捕获的类型错误:无法读取属性'型号'builder.js中未定义的
- 如何在vue.js中添加v-model动态创建的html
- Vue js 在输入字段中对 v-model 应用过滤器
- Use $.get() or this.model.save() (Backbone.js)
- 为什么backbone.js model.save()会更改属性hash
- backbone.js:model.save()总是成功的,尽管它应该't
- Ember.js加载模板上的Per-Model Promise状态
- 主干.js当服务器数据为空时 model.fetch
- 主干js this.model.get不是一个函数
- 如何将计算值绑定到 Angular 中的 ng-model 字段.js以便我可以使用 Ruby on Rails 将完整
- 主干.js Model.get() 返回 undefined, 范围使用 coffeescript + coffee t
- Angular JS如何将值从rootscope传递到ng-model
- Vue js v-model inside a bootstrap popover content
- 如何使用Excel Builder(.js)
- 使用“get”应该是有问题的.model-builder.js中的方法