0

我在使用 AngularJS 工厂从数据库显示产品信息时遇到问题。基本上它是一个购物车应用程序,我对其进行了修改以显示数据库中的产品,而不是硬编码数组。

这是主要应用程序文件源代码(app.js):

'use strict';

var shop = angular.module('shop', []);

// create a data service that provides a store and a shopping cart that
// will be shared by all views (instead of creating fresh ones for each view)
shop.factory("DataService",['$http', function($http) {
    // create store
    var myStore = new store($http);

    // return data object with store and cart
    return {
       store: myStore
       //cart: myCart ignore for now
    }
}]);

// adding the config on the module
shop.config(function($routeProvider) {
      $routeProvider // angular object, injected dynamically
        .when('/', // we show the store on the root
          {
            controller: 'StoreController',
            templateUrl: 'partials/store.htm'
          })
        .when('/cart',
          {
            controller: 'CartController',
            templateUrl: 'partials/cart.htm'
          })
        .when('/checkout',
          {
            controller: 'CheckoutController',
            templateUrl: 'partials/checkout.htm'
          })
       .when('/invoice',
          {
            controller: 'InvoiceController',
            templateUrl: 'partials/invoice.htm'
          })
       .otherwise({ redirectTo: '/' }); // store
    });

var controllers = {};
controllers.StoreController = function($scope, $routeParams, DataService) {
  $scope.store = DataService.store;
  console.log($scope.store);
  //$scope.cart = DataService.cart;
}

我检索数据的商店源代码(store.js):

function store($http) {
  this.products = [];
  this.url = 'php/db.php';
  this.fields = [
    'product_id',
    'product_name', 
    'product_description', 
    'product_price'
  ];
  this.products = this.getProducts($http);
}

store.prototype.getProducts = function($http) {
  $http.post(this.url, { "action" : 'products', "fields" : this.fields })
    .success(function(data, status) {
      //$scope.result = data; // Show result from server in our <pre></pre> element
      //return data;
      this.products = data;
    })
    .error(function(data, status) {
      //return data || "Request failed";
      //this.status = status;        
      this.products = [];
  }); 
}

store.prototype.getProduct = function (sku) {
  for (var i = 0; i < this.products.length; i++) {
    if (this.products[i].sku == sku)
      return this.products[i];
  }
  return null;
}

谁能告诉我我在这里做错了什么?

  • 为什么我不能将我的 this.product 变量设置为数据库结果?
  • 我还想用更多功能扩展产品类以将项目保存到数据库中,我该怎么做呢?

非常感谢任何建议。

问候

更新

我在下面添加了 app.js 代码,当从商店类 (store.js) 访问数据时,控制器 (StoreController) 出现问题。它仍然显示一个空数组。我已经按照 meconroy 的建议更改了我的代码。

应用程序.js

'use strict';

var shop = angular.module('shop', []);


shop.factory("DataService",['$http', '$q', function($http, $q) {
    // create store
    var myStore = new store($http, $q);
    return {
       store: myStore      
    }
}]);


// adding the config on the module
shop.config(function($routeProvider) {
      $routeProvider // angular object, injected dynamically
        .when('/', // we show the store on the root
          {
            controller: 'StoreController',
            templateUrl: 'partials/store.htm'
          })
        .when('/cart',
          {
            controller: 'CartController',
            templateUrl: 'partials/cart.htm'
          })
        .when('/checkout',
          {
            controller: 'CheckoutController',
            templateUrl: 'partials/checkout.htm'
          })
       .when('/invoice',
          {
            controller: 'InvoiceController',
            templateUrl: 'partials/invoice.htm'
          })
       .otherwise({ redirectTo: '/' }); // store
    });

var controllers = {};
controllers.StoreController = function($scope, $http, $routeParams, DataService) {
  $scope.store = DataService.store;              
}

shop.controller(controllers); 
4

1 回答 1

1
function store($http) {
    this.products = [];
    this.url = 'php/db.php';
    this.fields = ['product_id', 'product_name', 'product_description', 'product_price'];
    this.products = this.getProducts($http);
}

store.prototype.getProducts = function ($http) {
    return $http.post(this.url, {
        "action": 'products',
        "fields": this.fields
    })
    .success(function (data, status) {
        return data;
    })
    .error(function (data, status) { 
        return [];
    });
}

当您返回时,$http.post您将返回promise它创建的内容,因此this.products将包含$http承诺。当调用从服务器返回时,promise 由在这些函数中返回数据的successor函数解析,将变量设置为返回的值。errorthis.products

在这种情况下this.products = [],将立即被 Promise 所取代,$http.如果您尝试在解决发生之前访问应用程序中的该数据,您将取回它包含的 Promise,如果您尝试在其他功能中使用它可能会导致问题,就好像它包含您需要的数组。您可以使用$q.when“等待”承诺解决然后分配返回的数据,因此如果您尝试在this.products其他地方使用,那么它仍然会包含一个空数组,因此类似的代码this.products.length仍然可以工作而不是抛出错误。因此,您可以执行以下操作:

function store($http,$q) {
    this.products = [];
    this.url = 'php/db.php';
    this.fields = ['product_id', 'product_name', 'product_description', 'product_price'];
    $q.when(this.getProducts($http)).then(function(data){ this.products = data; });
}

如果您决定走这条路,请注意您需要注入$q您的服务,然后在创建类期间通过您的new操作员将其传递。这将解决您在控制器中可能遇到的任何竞争情况。

当然,您也可以在控制器“控制”之前使用resolve提供的.when方法来解决和控制器依赖关系$routeProvider

于 2013-10-24T14:03:35.650 回答