我正在尝试设置一些基本方案,并使用LoopBack找出其实际的灵活性和可用性。
其中一个是在从db(例如MySQL)处理源数据期间修改结果JSON对象中某些属性的值的必要性。
我使用以下版本:
strong-cli v2.5.5(node v0.10.29) node-inspector v0.7.4 strong-build v0.1.0 strong-cluster-control v0.4.0 强注册表v1.1.0 strong-supervisor v0.2.3(strong-agent v0.4.9,strong-cluster-control v0.4.0) loopback-datasource-juggler v1.6.2 loopback-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`)
)
并填写了一些简单的数据。
要在LoopBack中定义模型,我使用了文件" 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"对象
当我尝试运行LoopBack然后通过StrongLoop API Explorer发送请求时:
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"
}
正如您所见,"已启用"属性最终由" getter"方法但是:
' model-builder.js的源代码'在loopback-datasource-juggler(第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
}
},
解释原因。 '电话' method只有一个参数(this)代表' this'被调用函数中的对象并没有第二个参数代表参数' v'在被调用的函数中(与How do I create getter and setter overrides?上的Raymond Feng的答案有关)。
问题还在于这个'在里面' getter' method始终表示包含模型的所有属性的对象:
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"的想法吗?方法好吗?
非常感谢。
Milos Lapis MLC
更新
非常感谢雷蒙德的回答。
一开始我认为,但是当我使用类似的东西时:
City.getter["enabled"] = function() {
return this.enabled + "x"
};
当我请求时,节点立即崩溃:
localhost:3000/api/cities/1
带错误的:RangeError:超出最大调用堆栈大小
这就是为什么我认为你的实现有点不同。有什么不对吗?
我应该用什么来添加' x'从db?
中检索到的实际值感谢。
Milos Lapis MLC
答案 0 :(得分:1)
JavaScript getter函数采用以下格式:
function() {
// this is the object instance owning the property
}
请注意,getter函数不接受任何参数,接收者是拥有该属性的对象实例。例如:
myModelInstance.myProperty将使用此设置调用getter函数myModelInstance.See more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects。
答案 1 :(得分:1)
在您的示例代码中,您将递归调用已定义的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"
};