2013-10-24 2 views
0

У меня возникла проблема с отображением информации о продукте из базы данных с использованием фабрики AngularJS . В основном это приложение корзины покупок, которое я модифицировал для отображения продуктов из базы данных, а не жестко закодированного массива.Как получить данные с помощью фабрики AngularJS?

Heres файл главного приложения исходный код (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 ниже, я имею вопрос с контроллером (StoreController), когда доступ к данным из класса магазина (store.js) , Он по-прежнему показывает пустой массив. Я изменил свой код, как предложил 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); 
+0

DataService.store вернуть обещание, так что вам нужно решить, чтобы поймать Значение. И кажется, что вы храните функцию, не возвращает объект результата ... вам нужно вернуть этот объект. Можете ли вы создать пример plunker с полной реализацией фабричной фабрики? –

+0

Посмотрите этот хороший пример приложения angularjs https://github.com/andreev-artem/angular_experiments/tree/master/examples/architecture и здесь http://jsfiddle.net/u5gV2/ для простого кеша памяти. –

+0

Возвращаемые данные не определены. в коде я устанавливаю переменную this.products в значение, которое возвращается в обработчике успеха. – QCar

ответ

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 обещание. Когда вызов возвращается с сервера, обещание разрешается с помощью функций success или error, возвращающих данные в этих функциях, задает переменную this.products тому, что возвращается.

В этом случае this.products = [] становится заменен сразу на обещании от $http. Если вы пытаетесь получить доступ к этим данным в приложении перед решительность произойдет, вы получите обратно обещание он содержит, которые могут вызвать проблемы, если вы пытаетесь использовать он в других функциях, как будто он содержит требуемый массив. Вы можете использовать $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 для разрешения и зависимостей контроллера предшествующего уровня к контроллеру, принимая «контроль»

+0

Спасибо за ваш ответ, я изменил свой код и обновил вопрос с помощью своих контроллеров. Просто нужно немного больше направлений. Благодаря! – QCar

+0

Вы также изменили свой 'store.js', чтобы добавить в' $ q'? –

+0

Да, я сделал, function store ($ http, $ q) {... – QCar

Смежные вопросы