模型实例替换为远程方法导致 Angular 调用 Loopback
Model instance replaced with remote method result in Angular call to Loopback
我有一个带有 Angular 前端的 Loopback API,并且在尝试调用非静态远程方法时看到了一些奇怪的行为。
我已经把它归结为这个例子。拨打这样的电话时:
$scope.myInstance = MyModel.findOne({}, function success(value){
$scope.greeting = value.$prototype$hello({}, function success(){});
});
我发现 $scope.myInstance 最终包含对 $prototype$hello 的调用结果,而 $scope.greeting 是空的。 MyModel 是用这样的远程调用定义的:
module.exports = function(MyModel) {
MyModel.prototype.hello = function(cb) {
cb(null,"Hello: " + this.name);
}
MyModel.remoteMethod(
'hello',
{
isStatic: false,
http: { verb: 'get' },
returns: {arg: 'message', type: 'string'}
}
);
};
如果我的模板中有这个:
Greeting = {{ greeting }}, Instance = {{ myInstance }}
我明白了:
Greeting = {}, Instance = {"message":"Hello: Test","$promise":{},"$resolved":true}
用问候语结果清楚地代替了模型实例。我希望在实例变量中看到模型实例:
Greeting = {}, Instance = Instance = {"name":"Test","id":1,"$promise":{},"$resolved":true}
加载过程中模型会短暂闪烁。
我可以通过检索模型的额外一次性实例来解决这个问题,但我希望有人知道为什么会发生这种情况,以及是否有更清洁的解决方案。
2015 年 8 月 12 日更新: 我创建了一个 Plunker 来演示这个问题 here, but this only contains the client-side JS. For the full loopback project, I've added the code to a GitHub repo
有趣的是,Safari 下的行为略有不同,它根本不呈现实例:
Greeting = {}, Instance =
最初描述的行为见于 Chrome。
我检查了你的 plunker,我想我在这里遇到了问题,你的代码是:
$scope.myInstance = MyModel.findOne({}, function success(value){
$scope.greeting = value.$prototype$hello({}, function success(){});
});
让我们暂时忘记成功函数,findone()
函数 returns 您从 mongodb 请求的文档,正如我认为的那样,这自然意味着返回的文档或查询将存储在 $scope.myInstance
中,这就是您的应用程序的行为方式。
现在对于成功函数,它试图调用响应对象(值)中不存在的 value.$prototype$hello
,因此值为 undefined
并且存储在 $scope.greeting
中,这就是为什么它显示为空。
为什么 $prototype$hello
是 undefined
很简单,它是一个原型对象,如果它是您应用程序的一部分,但您正试图通过一个没有它的响应对象访问这个函数.
我希望这能回答你的问题
编辑:
问题出在这一行
$scope.greeting = value.$prototype$hello({}, function success(){});
就这样制作:
value.$prototype$hello({}, function success(val){$scope.greeting = val.message;},function error(err){console.log(err);});
编辑 2
将你的代码改成这样:
ModelA.findOne({}, function success(value){
//debugger;
value.$prototype$hello({}, function success(val){$scope.greeting = val.message;},function error(err){console.log(err);});
}).$promise.then(function(res) {
$scope.myInstance = res;
});
这样,在解决承诺之前,您的变量中不会有虚假数据。
而且,响应对象具有 $promise 和 $resolved 属性是完全正常的,因为它是一个资源承诺对象
编辑 3
现在在你澄清了你上一条评论的问题后,我能够理解它,我正在寻找其他东西,但无论如何它们是相关的。
发生的是冲突,您正在执行两个异步调用,您应该这样对待它们,代码应该是这样的:
ModelA.findOne({}).$promise.then(function(value) {
$scope.myInstance = value;
var v2 = angular.copy(value);
v2.$prototype$hello({},
function (val){
$scope.greeting = val.message;
},
function (err){console.log(err);}
);
});
如果您需要有关代码的更多信息,请告诉我
我有一个带有 Angular 前端的 Loopback API,并且在尝试调用非静态远程方法时看到了一些奇怪的行为。
我已经把它归结为这个例子。拨打这样的电话时:
$scope.myInstance = MyModel.findOne({}, function success(value){
$scope.greeting = value.$prototype$hello({}, function success(){});
});
我发现 $scope.myInstance 最终包含对 $prototype$hello 的调用结果,而 $scope.greeting 是空的。 MyModel 是用这样的远程调用定义的:
module.exports = function(MyModel) {
MyModel.prototype.hello = function(cb) {
cb(null,"Hello: " + this.name);
}
MyModel.remoteMethod(
'hello',
{
isStatic: false,
http: { verb: 'get' },
returns: {arg: 'message', type: 'string'}
}
);
};
如果我的模板中有这个:
Greeting = {{ greeting }}, Instance = {{ myInstance }}
我明白了:
Greeting = {}, Instance = {"message":"Hello: Test","$promise":{},"$resolved":true}
用问候语结果清楚地代替了模型实例。我希望在实例变量中看到模型实例:
Greeting = {}, Instance = Instance = {"name":"Test","id":1,"$promise":{},"$resolved":true}
加载过程中模型会短暂闪烁。
我可以通过检索模型的额外一次性实例来解决这个问题,但我希望有人知道为什么会发生这种情况,以及是否有更清洁的解决方案。
2015 年 8 月 12 日更新: 我创建了一个 Plunker 来演示这个问题 here, but this only contains the client-side JS. For the full loopback project, I've added the code to a GitHub repo
有趣的是,Safari 下的行为略有不同,它根本不呈现实例:
Greeting = {}, Instance =
最初描述的行为见于 Chrome。
我检查了你的 plunker,我想我在这里遇到了问题,你的代码是:
$scope.myInstance = MyModel.findOne({}, function success(value){
$scope.greeting = value.$prototype$hello({}, function success(){});
});
让我们暂时忘记成功函数,findone()
函数 returns 您从 mongodb 请求的文档,正如我认为的那样,这自然意味着返回的文档或查询将存储在 $scope.myInstance
中,这就是您的应用程序的行为方式。
现在对于成功函数,它试图调用响应对象(值)中不存在的 value.$prototype$hello
,因此值为 undefined
并且存储在 $scope.greeting
中,这就是为什么它显示为空。
为什么 $prototype$hello
是 undefined
很简单,它是一个原型对象,如果它是您应用程序的一部分,但您正试图通过一个没有它的响应对象访问这个函数.
我希望这能回答你的问题
编辑:
问题出在这一行
$scope.greeting = value.$prototype$hello({}, function success(){});
就这样制作:
value.$prototype$hello({}, function success(val){$scope.greeting = val.message;},function error(err){console.log(err);});
编辑 2
将你的代码改成这样:
ModelA.findOne({}, function success(value){
//debugger;
value.$prototype$hello({}, function success(val){$scope.greeting = val.message;},function error(err){console.log(err);});
}).$promise.then(function(res) {
$scope.myInstance = res;
});
这样,在解决承诺之前,您的变量中不会有虚假数据。 而且,响应对象具有 $promise 和 $resolved 属性是完全正常的,因为它是一个资源承诺对象
编辑 3
现在在你澄清了你上一条评论的问题后,我能够理解它,我正在寻找其他东西,但无论如何它们是相关的。 发生的是冲突,您正在执行两个异步调用,您应该这样对待它们,代码应该是这样的:
ModelA.findOne({}).$promise.then(function(value) {
$scope.myInstance = value;
var v2 = angular.copy(value);
v2.$prototype$hello({},
function (val){
$scope.greeting = val.message;
},
function (err){console.log(err);}
);
});
如果您需要有关代码的更多信息,请告诉我