【问题标题】:Model instance replaced with remote method result in Angular call to Loopback用远程方法替换模型实例导致对 Loopback 的 Angular 调用
【发布时间】:2015-08-16 06:20:58
【问题描述】:

我有一个带有 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 }}

我明白了:

问候 = {},实例 = {"message":"Hello: Test","$promise":{},"$resolved":true}

用问候结果清楚地代替模型实例。我希望在 Instance 变量中看到模型实例:

问候 = {},实例 = 实例 = {"name":"Test","id":1,"$promise":{},"$resolved":true}

加载过程中模型短暂闪烁。

我可以通过检索模型的其他一次性实例来解决此问题,但我希望有人知道为什么会发生这种情况以及是否有更清洁的解决方案。

2015 年 8 月 12 日更新:我创建了一个 Plunker 来演示此问题 here,但这仅包含客户端 JS。对于完整的环回项目,我已将代码添加到 GitHub repo

有趣的是,在 Safari 下的行为略有不同,根本不渲染实例:

问候 = {},实例 =

最初描述的行为是在 Chrome 下看到的。

【问题讨论】:

  • 创建一个 plunker 或 fiddle 以便我们真正提供帮助。
  • 感谢您的建议,请参阅我的更新。请注意,这是一个 Loopback (Node.js) 项目,因此 Plunker 只会显示客户端部分。

标签: angularjs loopbackjs


【解决方案1】:

我检查了你的 plunker,我想我在这里遇到了问题,你的代码是:

$scope.myInstance = MyModel.findOne({}, function success(value){
  $scope.greeting = value.$prototype$hello({}, function success(){});
});

让我们暂时忘记成功函数,findone() 函数从 mongodb 中返回您请求的文档,我认为,这意味着返回的文档或查询自然会存储在 $scope.myInstance 中,这就是您的应用程序正在运行。 现在对于成功函数,它正在尝试调用响应对象(值)中不存在的value.$prototype$hello,因此该值是undefined,并且存储在$scope.greeting 中,这就是它显示为空的原因。

为什么$prototype$helloundefined 很简单,如果它是您的应用程序的一部分,它就是一个原型对象,但您正试图通过一个没有它的响应对象来访问此函数。

我希望这能回答你的问题

编辑:

问题出在这一行

 $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);}
  );
});

如果您需要有关代码的更多信息,请告诉我

【讨论】:

  • findOne 的结果暂时存储在 $scope.myInstance 中,但这很快被 $prototype$hello 的结果(确实存在)所取代。我应该以不同的方式访问 $prototype$hello(..) 吗?我对 Angular 中的资源处理不太熟悉。
  • 附带说明一下,我通过添加调试器行并监视value 找到了$prototype$hello。
  • 不知道为什么我被否决了,无论如何,找到问题,检查编辑
  • 您是否在 plunker 中运行了您建议的编辑?这正确设置了问候语,但$scope.myInstance 仍设置为value.$prototype$hello 返回的承诺,而它应该是findOne 调用的结果。
  • 终于稳定了,问题是 $prototype$hello 如果你在使用它解决问题的函数之前克隆它会覆盖'value',更新的代码在编辑3中
猜你喜欢
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 2015-01-29
  • 2016-05-21
  • 1970-01-01
  • 2012-02-27
相关资源
最近更新 更多