开发者问题收集

如何以 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