【问题标题】:Get data from Parse.com using AngularJS factory使用 AngularJS 工厂从 Parse.com 获取数据
【发布时间】:2020-01-08 16:28:34
【问题描述】:

我正在使用AngularJS (v1.6.7) 和Parse Server (v2.3.3) 开发一个电子商务网络应用程序。

我在 Parse Server 中创建了 CategoryProduct 类。我正在尝试为每个类别获取一定数量的产品。

例如,在首页中,每个类别将检索 20 个产品。其他页面中的产品数量发生变化。

我想使用一个工厂来获取任何类别的给定数量的产品(amountcategory 的产品将作为参数传递给函数)。所以我可以在其他控制器中重用它。

ProductsFactory工厂:

sebetimapp.factory('ProductsFactory', ['$q', function($q){
    Parse.initialize('MY_APP_ID', 'JS_KEY');
    Parse.serverURL = 'https://parseapi.back4app.com/';

    let fac = {};

    fac.getProducts = function(cat, lmt) {
        let Category = Parse.Object.extend('Category'),
            qr = new Parse.Query(Category);

        qr.get(cat, {
            success: function (res) {
                let product_dfd = $q.defer(),
                    Product = Parse.Object.extend('Product'),
                    query = new Parse.Query(Product);

                query.include('category');

                query.equalTo('category', res);

                if (lmt) {
                    query.limit(lmt);
                }

                query.find({
                    success: function(results) {
                        product_dfd.resolve(results);
                    },
                    error: function(err) {
                        product_dfd.reject(results);
                    }
                });

                return product_dfd.promise;
            },
            error: function(object, error) {
                //
            }
        });
    };

    return fac;
}]);

productsCtrl控制器:

sebetimapp.controller('productsCtrl', ['$scope', '$log', '$location', '$q', 'ProductsFactory', function($scope, $log, $location, $q, ProductsFactory) {
    let params = $location.search(); // To grab category ID from URL.

    ProductsFactory.getProducts(params.cat, 20).then(function(response) {
        $log.log('Successfully retrieved products.');
    }, function(error) {
        $log.log('Unable to get products.');
    });
}]);

当我执行时,出现错误:

TypeError: 无法读取未定义的属性“then”

但如果我不使用这个工厂并在我的控制器中定义getProducts() 函数,它就可以正常工作。

为什么会这样?我是AngularJS 的新手。任何帮助将不胜感激。

【问题讨论】:

  • 您正在内部函数中创建并返回 $q 承诺,而不是在 getProducts 中。还可以想象 Parse 也有承诺

标签: javascript angularjs parse-platform angularjs-factory


【解决方案1】:

.then() 方法仅适用于Promises。您的函数似乎没有返回任何内容(因此,.then() 不可用)。

这可能会有所帮助:

sebetimapp.factory('ProductsFactory', ['$q', function($q) {
  Parse.initialize('MY_APP_ID', 'JS_KEY');
  Parse.serverURL = 'https://parseapi.back4app.com/';
  var fac = {};
  fac.getProducts = function(cat, lmt) {
    var Category = Parse.Object.extend('Category'),
      qr = new Parse.Query(Category);
    return qr.get(cat)
      .then(function(res) {
        var Product = Parse.Object.extend('Product'),
          query = new Parse.Query(Product);
        query.include('category');
        query.equalTo('category', res);
        if (lmt) {
          query.limit(lmt);
        }
        return query.find();
      });
  };
  return fac;
}]);

Parse JS API 中的大多数方法都会返回 Promise。您可以直接使用它们(而不是使用 successerror 回调)。自从我从事 Parse 工作以来已经很久了(我认为它不再可用)所以你可能必须自己弄清楚细节。方便链接:http://docs.parseplatform.org/js/guide/#promises

TLDR;您的工厂函数需要返回一个承诺,但没有返回任何内容,因此 .then() 不可用

编辑:这是对原始代码进行最小更改的另一种方法(但是,这不是最好的方法)

sebetimapp.factory('ProductsFactory', ['$q', function($q) {
  Parse.initialize('MY_APP_ID', 'JS_KEY');
  Parse.serverURL = 'https://parseapi.back4app.com/';
  var fac = {};
  fac.getProducts = function(cat, lmt) {
    var Category = Parse.Object.extend('Category'),
      qr = new Parse.Query(Category),
      // Move the deffered object out of the inner function
      product_dfd = $q.defer();
    qr.get(cat, {
      success: function(res) {
        var Product = Parse.Object.extend('Product'),
          query = new Parse.Query(Product);
        query.include('category');
        query.equalTo('category', res);
        if (lmt) {
          query.limit(lmt);
        }
        query.find({
          success: function(results) {
            product_dfd.resolve(results);
          },
          error: function(err) {
            product_dfd.reject(results);
          }
        });
      },
      error: function(object, error) {}
    });
    // Return the deferred object
    return product_dfd.promise;
  };
  return fac;
}]);

【讨论】:

  • 我尝试了你的第一个 sn-p,它成功了。为什么比第二个好?
  • 第一个可能更干净,更易读,因为它只使用 Promise。将 Promise 与回调模式混合通常会创建难以阅读/推理的代码库。为了一致性,最好只坚持承诺或只使用回调。此外,promise 将是更好的选择,因为它们是为处理“回调地狱”而发明的。我建议阅读 Promises 并正确使用它们(我可以为它们担保,因为了解它们使我的代码更加简洁)
猜你喜欢
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多