如何使用AngularJS工厂检索数据?

时间:2013-10-24 10:45:56

标签: javascript php sql-server-2008 angularjs

我在使用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)的问题。 它仍然显示一个空数组。我按照m.e.conroy的建议更改了我的代码。

app.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); 

1 个答案:

答案 0 :(得分: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承诺。当调用从服务器返回时,承诺由successerror函数解析,返回这些函数中的数据将变量this.products设置为返回的内容。

在这种情况下,this.products = []正在被$http.的承诺立即替换。如果您在解决问题发生之前尝试访问应用程序中的数据,您将收回它所包含的承诺如果您尝试在其他函数中使用它,如果它包含您需要的数组,则会导致问题。您可以使用$q.when来“等待”承诺解析然后分配返回的数据,因此如果您尝试在其他地方使用this.products,那么它仍将包含一个空数组,因此代码如{ {1}}仍然有效,而不是抛出错误。所以你可以做到以下几点:

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来解析控制器依赖关系