如何以 angular 2 风格将 angular 1.2 服务更新至 1.5
2016-06-03
259
https://github.com/snapjay/ngCart/blob/master/src/ngCart.js#L30 我需要将此 repo 从 1.2 angular 更新到 1.5,并在将来更新到 2.0 我开始从 addToCart 组件升级此示例
import * as angular from 'angular';
import angularMeteor from 'angular-meteor';
import { name as ngCart } from '../../../api/ngCart/ngCart';
import './addToCart.html';
class AddToCart {
constructor($scope, $reactive) {//, ngCart
//ngCart object here should service return function?
//angular_angular.js?hash=08f63d2…:13439 TypeError: _apiNgCartNgCart.name.getItemById is not a function
'ngInject';
$reactive(this).attach($scope);
if (this.inCart()) {
this.q = ngCart.getItemById(this.id).getQuantity();
} else {
this.q = parseInt(this.quantity);
}
this.qtyOpt = [];
for (var i = 1; i <= this.quantityMax; i++) {
this.qtyOpt.push(i);
}
}
inCart() {
console.log("cart " + ngCart);
return ngCart.getItemById(this.id);
}
}
const name = 'addToCart';
// create a module
export default angular.module(name, [
angularMeteor,
ngCart
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
bindings: {
id: '@',
name: '@',
quantity: '@',
quantityMax: '@',
price: '@',
data: '='
},
controller: AddToCart
});
它给了我以下错误
TypeError: _apiNgCartNgCart.name.getItemById is not a function
at AddToCart.inCart (addToCart.js:39)
这里是 ngCart 服务
import { name as ngCartItem } from './ngCartItem';
import { name as store } from './store';
class NgCart {
constructor($scope, $reactive, $window) {
'ngInject';
$reactive(this).attach($scope);
}
$onInit() {
// $rootScope.$on('ngCart:change', function(){ // i shouldn't user rooutscope here
// ngCart.$save();
// });
if (angular.isObject(store.get('cart'))) {
this.$restore(store.get('cart'));
} else {
this.init();
}
}
init() {
this.$cart = {
shipping: null,
taxRate: null,
tax: null,
items: []
};
};
addItem(id, name, price, quantity, data) {
var inCart = this.getItemById(id);
if (typeof inCart === 'object') {
//Update quantity of an item if it's already in the cart
inCart.setQuantity(quantity, false);
// $rootScope.$broadcast('ngCart:itemUpdated', inCart);
} else {
var newItem = new ngCartItem(id, name, price, quantity, data);
this.$cart.items.push(newItem);
// $rootScope.$broadcast('ngCart:itemAdded', newItem);
}
// $rootScope.$broadcast('ngCart:change', {});
};
getItemById(itemId) {
var items = this.getCart().items;
var build = false;
angular.forEach(items, function (item) {
if (item.getId() === itemId) {
build = item;
}
});
return build;
};
setShipping(shipping) {
this.$cart.shipping = shipping;
return this.getShipping();
};
getShipping() {
if (this.getCart().items.length == 0) return 0;
return this.getCart().shipping;
};
setTaxRate(taxRate) {
this.$cart.taxRate = +parseFloat(taxRate).toFixed(2);
return this.getTaxRate();
};
getTaxRate() {
return this.$cart.taxRate
};
getTax() {
return +parseFloat(((this.getSubTotal() / 100) * this.getCart().taxRate)).toFixed(2);
};
setCart(cart) {
this.$cart = cart;
return this.getCart();
};
getCart() {
return this.$cart;
};
getItems() {
return this.getCart().items;
};
getTotalItems() {
var count = 0;
var items = this.getItems();
angular.forEach(items, function (item) {
count += item.getQuantity();
});
return count;
};
getTotalUniqueItems() {
return this.getCart().items.length;
};
getSubTotal() {
var total = 0;
angular.forEach(this.getCart().items, function (item) {
total += item.getTotal();
});
return +parseFloat(total).toFixed(2);
};
totalCost() {
return +parseFloat(this.getSubTotal() + this.getShipping() + this.getTax()).toFixed(2);
};
removeItem(index) {
var item = this.$cart.items.splice(index, 1)[0] || {};
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
removeItemById(id) {
var item;
var cart = this.getCart();
angular.forEach(cart.items, function (item, index) {
if (item.getId() === id) {
item = cart.items.splice(index, 1)[0] || {};
}
});
this.setCart(cart);
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
empty() {
// $rootScope.$broadcast('ngCart:change', {});
this.$cart.items = [];
$window.localStorage.removeItem('cart');
};
isEmpty() {
return (this.$cart.items.length > 0 ? false : true);
};
toObject() {
if (this.getItems().length === 0) return false;
var items = [];
angular.forEach(this.getItems(), function (item) {
items.push(item.toObject());
});
return {
shipping: this.getShipping(),
tax: this.getTax(),
taxRate: this.getTaxRate(),
subTotal: this.getSubTotal(),
totalCost: this.totalCost(),
items: items
}
};
$restore(storedCart) {
var _self = this;
_self.init();
_self.$cart.shipping = storedCart.shipping;
_self.$cart.tax = storedCart.tax;
angular.forEach(storedCart.items, function (item) {
_self.$cart.items.push(new ngCartItem(item._id, item._name, item._price, item._quantity, item._data));
});
this.$save();
};
$save() {
return store.set('cart', JSON.stringify(this.getCart()));
}
}
const name = 'ngCart';
// create a module
export default angular.module(name, [
angularMeteor,
ngCartItem,
store
]).service(name, {
controllerAs: name,
controller: NgCart
});
如何在 1.5 中导入服务? 我正在使用 angular-meteor 并遵循 本 教程
而且服务中不能有作用域 // 此控制器抛出未知提供程序错误,因为 // 作用域对象无法注入到服务中。
https://docs.angularjs.org/error/ $injector/unpr?p0=$scopeProvider%20%3C-%20$scope%20%3C-%20ngCart
2个回答
找到解决方案 1.5+ angular 服务应该是这样的
import { name as store } from './store';
class NgCart {
constructor($reactive, $window) {
'ngInject';
console.log("ngcart service constructor");
}
getItemById (itemId) {
console.log("hello FROM SERVICE!");
}
}
const name = 'NgCart';
// create a module
export default angular.module(name, [
angularMeteor
]).service(name, NgCart);
以及如何在 angular 组件中使用它
import * as angular from 'angular';
import angularMeteor from 'angular-meteor';
import { name as NgCart } from '../../../api/ngCart/ngCart';
import './addToCart.html';
class AddToCart {
constructor($scope, $reactive, NgCart) {
'ngInject';
this.NgCart = NgCart;
}
$onInit() {
if (this.inCart()) {
this.q = this.NgCart.getItemById(this.id).getQuantity();
} else {
this.q = parseInt(this.quantity);
}
this.qtyOpt = [];
for (var i = 1; i <= this.quantityMax; i++) {
this.qtyOpt.push(i);
}
}
inCart() {
console.log("cart " + this.NgCart);
console.dir(this.NgCart);
return this.NgCart.getItemById(this.id);
}
}
const name = 'addToCart';
// create a module
export default angular.module(name, [
angularMeteor,
NgCart
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
bindings: {
id: '@',
name: '@',
quantity: '@',
quantityMax: '@',
price: '@',
data: '='
},
controller: AddToCart
});
真正有用的信息在 Todd Motto angular 1.x es2015 风格指南
Anatoly Ruchka
2016-06-17
对于您的 addToCart 组件,请尝试以下操作:
import * as angular from 'angular';
import angularMeteor from 'angular-meteor';
import { name as ngCart } from '../../../api/ngCart/ngCart';
import './addToCart.html';
class AddToCart {
constructor($scope, $reactive, ngCart) {
'ngInject';
$reactive(this).attach($scope);
this._ngCart = ngCart;
if (this.inCart()) {
this.q = this._ngCart.getItemById(this.id).getQuantity();
} else {
this.q = parseInt(this.quantity);
}
this.qtyOpt = [];
for (var i = 1; i <= this.quantityMax; i++) {
this.qtyOpt.push(i);
}
}
inCart() {
console.log("cart " + ngCart);
return this._ngCart.getItemById(this.id);
}
}
const name = 'addToCart';
// create a module
export default angular.module(name, [
angularMeteor,
ngCart
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
bindings: {
id: '@',
name: '@',
quantity: '@',
quantityMax: '@',
price: '@',
data: '='
},
controller: AddToCart
});
对于您的服务,请尝试以下操作(服务没有范围):
import { name as ngCartItem } from './ngCartItem';
import { name as store } from './store';
class NgCart {
$onInit() {
// $rootScope.$on('ngCart:change', function(){ // i shouldn't user rooutscope here
// ngCart.$save();
// });
if (angular.isObject(store.get('cart'))) {
this.$restore(store.get('cart'));
} else {
this.init();
}
}
init() {
this.$cart = {
shipping: null,
taxRate: null,
tax: null,
items: []
};
};
addItem(id, name, price, quantity, data) {
var inCart = this.getItemById(id);
if (typeof inCart === 'object') {
//Update quantity of an item if it's already in the cart
inCart.setQuantity(quantity, false);
// $rootScope.$broadcast('ngCart:itemUpdated', inCart);
} else {
var newItem = new ngCartItem(id, name, price, quantity, data);
this.$cart.items.push(newItem);
// $rootScope.$broadcast('ngCart:itemAdded', newItem);
}
// $rootScope.$broadcast('ngCart:change', {});
};
getItemById(itemId) {
var items = this.getCart().items;
var build = false;
angular.forEach(items, function (item) {
if (item.getId() === itemId) {
build = item;
}
});
return build;
};
setShipping(shipping) {
this.$cart.shipping = shipping;
return this.getShipping();
};
getShipping() {
if (this.getCart().items.length == 0) return 0;
return this.getCart().shipping;
};
setTaxRate(taxRate) {
this.$cart.taxRate = +parseFloat(taxRate).toFixed(2);
return this.getTaxRate();
};
getTaxRate() {
return this.$cart.taxRate
};
getTax() {
return +parseFloat(((this.getSubTotal() / 100) * this.getCart().taxRate)).toFixed(2);
};
setCart(cart) {
this.$cart = cart;
return this.getCart();
};
getCart() {
return this.$cart;
};
getItems() {
return this.getCart().items;
};
getTotalItems() {
var count = 0;
var items = this.getItems();
angular.forEach(items, function (item) {
count += item.getQuantity();
});
return count;
};
getTotalUniqueItems() {
return this.getCart().items.length;
};
getSubTotal() {
var total = 0;
angular.forEach(this.getCart().items, function (item) {
total += item.getTotal();
});
return +parseFloat(total).toFixed(2);
};
totalCost() {
return +parseFloat(this.getSubTotal() + this.getShipping() + this.getTax()).toFixed(2);
};
removeItem(index) {
var item = this.$cart.items.splice(index, 1)[0] || {};
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
removeItemById(id) {
var item;
var cart = this.getCart();
angular.forEach(cart.items, function (item, index) {
if (item.getId() === id) {
item = cart.items.splice(index, 1)[0] || {};
}
});
this.setCart(cart);
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
empty() {
// $rootScope.$broadcast('ngCart:change', {});
this.$cart.items = [];
$window.localStorage.removeItem('cart');
};
isEmpty() {
return (this.$cart.items.length > 0 ? false : true);
};
toObject() {
if (this.getItems().length === 0) return false;
var items = [];
angular.forEach(this.getItems(), function (item) {
items.push(item.toObject());
});
return {
shipping: this.getShipping(),
tax: this.getTax(),
taxRate: this.getTaxRate(),
subTotal: this.getSubTotal(),
totalCost: this.totalCost(),
items: items
}
};
$restore(storedCart) {
var _self = this;
_self.init();
_self.$cart.shipping = storedCart.shipping;
_self.$cart.tax = storedCart.tax;
angular.forEach(storedCart.items, function (item) {
_self.$cart.items.push(new ngCartItem(item._id, item._name, item._price, item._quantity, item._data));
});
this.$save();
};
$save() {
return store.set('cart', JSON.stringify(this.getCart()));
}
}
const name = 'ngCart';
export default angular.module(name, [
angularMeteor,
ngCartItem,
store
]).service(name, NgCart);
Jesper
2016-06-03