使用AngularJS正确使用依赖注入

时间:2014-11-20 15:04:41

标签: angularjs

我第一次尝试学习AngularJS,我有以下文件,我自己创建。

Demo.html

<html ng-app="myApp">
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-route.min.js"></script>
        <script src="./modules.js"></script>
        <script src="./product.js"></script>
        <title>Your Shopping Cart</title>
    </head>
    <style>
        body {
            font-family: arial;
        }
        table {
            border-collapse: collapse;
        }
        table, th, td {
            border: 1px solid darkgray;
        }
        tr {
            background-color: slategray;
            color: white;
        }
        td {
            padding: 15px;
        }
        .outofstock {
            color: red;
        }
        .instock {
            color: green;
        }
    </style>
    <body ng-controller="CartController">
        <h1>Your Order</h1>
        <div ng-repeat="item in items">
            <span ng-bind="item.title"></span>
            <input ng-model="item.quantity" />
            <span ng-class="{instock: isInStock($index), outofstock: !isInStock($index)}" ng-bind="stockCheck($index)"></span>
            <span ng-bind="item.price | currency"></span>
            <span ng-bind="calculateCost(item.price, item.quantity) | currency"></span>
            <button ng-click="remove($index)">Remove</button>
        </div>
        <br />
        <table class="totals">
            <tr>
                <td><b>Nett Total: </b><span ng-bind="bill.totalCart | currency"></span></td>
                <td><b>Discount: </b><span ng-bind="bill.discount | currency"></span></td>
                <td><b>Sales Tax: </b><span ng-bind="bill.salesTax | currency"></span></td>
                <td><b>Gross Total: </b><span ng-bind="bill.subTotal | currency"></span></td>
            </tr>
        </table>
        <script>

        myApp.controller('CartController', [
            '$scope', 'appProduct', 
            function($scope,product) {
            $scope.salesTaxPercent = 20;

            $scope.bill = {};

            $scope.items = product.getProducts();

                $scope.remove = function(index) {
                    $scope.items.splice(index, 1);
                }

                $scope.stockCheck = function(index) {
                    if (isNaN($scope.items[index].quantity))
                        return 'Invalid quantity';

                    if ($scope.isInStock(index))
                        return ($scope.items[index].stock - $scope.items[index].quantity) + ' left in stock';
                    else
                        return 'Out of stock';                      
                }

                $scope.isInStock = function(index) {
                    var result = true;
                    if ($scope.items[index].quantity >= $scope.items[index].stock)
                        result = false;

                    return result;
                }

                $scope.calculateCost = function(price, qty) {
                    return price * qty;
                }

                var calculateTotals = function() {
                    var total = 0;
                    $scope.items.forEach(function(item) {
                        if (!isNaN(item.quantity))
                            total = total + $scope.calculateCost(item.price, item.quantity);
                    });
                    $scope.bill.totalCart = total;
                    $scope.bill.discount = total > 100 ? 10 : 0;
                    $scope.bill.salesTax = total * $scope.salesTaxPercent / 100
                    $scope.bill.subTotal = total - $scope.bill.discount + $scope.bill.salesTax;
                };

                $scope.$watch('items', calculateTotals, true);
            }
        ]);
        </script>
    </body>
</html>

modules.js

'use strict';

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

products.js

'use strict';

myApp.factory('appProduct', ['$q',
    function($q) {
        var $this = function() {
            angular.extend(this, {
                getProducts : getProducts
            });
        };

        function getProducts() {
            return {title: 'Paint pots', quantity: 8, price: 3.95, stock: 10},
                    {title: 'Polka dots', quantity: 17, price: 12.95, stock: 20},
                    {title: 'Pebbles', quantity: 5, price: 6.95, stock: 10};
        };
    }
]);

当我运行Demo.html文件时,我没有得到我在getProducts方法中嘲笑的3种产品。

我错过了什么吗?

2 个答案:

答案 0 :(得分:0)

运行此控制台时是否在控制台中出现任何错误?尝试在$scope.items = product.getProducts();上设置断点并检查产品的价值。

您的文件是否真的命名为产品 .js(强调尾随S)?我注意到您的<script>标记包含src="./product.js",如果找不到,则为Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to: Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

- 更新 -

添加了您提供的代码的JSFiddle http://jsfiddle.net/v30njcfu/1/

正如您在控制台中看到的那样,错误是

$this

这是因为在定义之前尝试使用myApp。检查浏览器开发人员工具的网络选项卡,检查module.js是否已加载。

此外,您的appProduct工厂正在创建一个变量this,它通过添加getProducts()函数来扩展this.getProducts = function() { ... },但这实际上并没有改变它的定义,所以它应该简化为{{ 1}}如同小提琴或至少return $this

答案 1 :(得分:0)

我已经设法找出问题所在 - 它是由getProducts中'Pebbles'数组元素中添加了错误的分号引起的。删除分号后,应用程序正常工作。