使用AngularJS

时间:2016-03-23 11:11:30

标签: python angularjs django angularjs-directive django-rest-framework

感谢您抽出宝贵时间阅读/提供反馈。这将是一个很长的帖子。

我最近完成了https://www.thinkster.io

上的Django + AngularJS教程

基于本教程,我构建了一个类似于教程的后端/前端,主要区别在于我使用的是产品而不是帖子。

由于某些奇怪的原因,IndexController继续加载我的product指令而不是products指令。

使用REST API / api / v1 / products /我可以看到所有产品对象。我假设应用程序的django部分工作。使用Mozilla调试器,我可以看到API调用有效,vm.products(数组)填充了所有Product对象。由于一些奇怪的原因,angularJS只显示最后一个对象。

由于这种情况,我已经重做了教程,它完美无瑕并重写了我的代码,这没有用,所以我转向你。

这是我的产品应用中的ViewSet:

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)
        return (permissions.AllowAny(),)

    def perform_create(self, serializer):
        instance = serializer.save()
        return super(ProductViewSet, self).perform_create(serializer)

这是root中的urls.py:

router = routers.SimpleRouter()
router.register('products', ProductViewSet)

urlpatterns = patterns(
    url(r'api/v1/', include(router.urls)),
    ....
)

现在在AngularJS部分。这是我写的产品服务。

(function () {
    'use strict';

    angular.module('app.products.services')
        .factory('Products', Products);

    Products.$inject = ['$http'];

    function Products($http) {
        var Products = {
            all: all,
            create:create
        };

        return Products;

        function all() {
            return $http.get('/api/v1/products/');
        }
        function create(name, description, price) {
            return $http.post('/api/v1/products/', {
                name:name,
                description:description,
                price:price
            });
        }
    }
})();

这是我写的产品控制器,它几乎是本教程的直接副本。

(function () {
    'use strict';

    angular.module('app.products.controllers')
        .controller('ProductsController', ProductsController);

    ProductsController.$inject = ['$scope'];

    function ProductsController($scope) {
        var vm = this;

        vm.columns = [];

        activate();

        function activate() {
            $scope.$watchCollection(function () { return $scope.products; }, render);
            $scope.$watch(function () { return $(window).width(); }, render);
        }
        function calculateNumberOfColumns() {
            var width = $(window).width();

            if (width >= 1200) {
                return 4;
            } else if (width >= 992) {
                return 3;
            } else if (width >= 768) {
                return 2;
            } else {
                return 1;
            }
        }
        function approximateShortestColumn() {
            var scores = vm.columns.map(columnMapFn);

            return scores.indexOf(Math.min.apply(this, scores));

            function columnMapFn(column) {
                var lengths = column.map(function (element) {
                    return element.content.length;
                });
                return lengths.reduce(sum, 0) * column.length;
            }
            function sum(m,n) {
                return m+n;
            }
        }
        function render(current, original) {
            if (current !== original) {
                vm.columns = [];

                for(var i = 0; i < calculateNumberOfColumns(); ++i) {
                    vm.columns.push([]);
                }
                for(var i = 0; i < current.length; ++i) {
                    var column = approximateShortestColumn();

                    vm.columns[column].push(current[i]);
                }
            }
        }
    }
})();

这是产品指令:

(function () {
    'use strict';

    angular.module('app.products.directives')
        .directive('product', product);

    function product() {
        var directive = {
            restrict: 'E',
            scope: {
                product:'='
            },
            templateUrl:'/static/templates/products/product.html'
        };
        return directive;
    }
})();

这是产品指令。

(function () {
    'use strict';

    angular.module('app.products.directives')
        .directive('products', products);

    function products() {
        var directive = {
            controller: 'ProductsController',
            controllerAs: 'vm',
            restrict: 'E',
            scope: {
                products : '='
            },
            templateUrl: '/static/templates/products/products.html'
        };
        return directive;
    }
})();

这是app.routes.js,类似于教程routes.js。

(function () {
    'use strict';

    angular.module('app.routes')
        .config(config);
    config.$inject = ['$routeProvider'];

    function config($routeProvider) {
        $routeProvider.when('/', {
            controller: 'IndexController',
            controllerAs: 'vm',
            templateUrl: '/static/templates/layout/index.html'
        }).when('/register', {
            controller: 'RegisterController',
            controllerAs: 'vm',
            templateUrl: '/static/templates/authentication/register.html'
        }).when('/login', {
            controller: 'LoginController',
            controllerAs: 'vm',
            templateUrl: '/static/templates/authentication/login.html'
        }).otherwise('/');
    }
}) ();

如此处所示,/由IndexController控制,以便进一步说明:index.controller.js

(function () {
    'use strict';

    angular.module('app.layout.controllers')
        .controller('IndexController', IndexController);

    IndexController.$inject = ['$scope', 'Authentication', 'Products', 'Snackbar'];

    function IndexController($scope, Authentication, Products, Snackbar) {
        var vm = this;
        vm.products = [];

        activate();

        function activate() {
            Products.all().then(productsSuccessFn, productsErrorFn);

            $scope.$on('product.created', function (event, obj) {
                vm.products.unshift(obj);
            });
            $scope.$on('product.created.error', function () {
                vm.products.shift();
            });

            function productsSuccessFn(data, status, headers, config) {
                vm.products = data.data;
            }
            function productsErrorFn(data, status, headers, config) {
                Snackbar.error(data.error);
            }
        }
    }
}) ();

现在为HTML页面。

这是index.html

<products products="vm.products" ng-show="vm.products && vm.products.length"></products>

product.html

<div class="row">
    <div class="col-sm-12">
        <div class="well">
            <div class="product">
                <div class="product__meta">
                    <a>{{ product.name }}</a>
                </div>
                <div class="product__content">
                    <p>{{ product.description }}</p>
                    <p>€{{ product.price }}</p>
                </div>
            </div>
        </div>
    </div>
</div>

products.html放在

<div class="row" ng-cloak>
    <div ng-repeat="column in vm.columns">
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
            <div ng-repeat="product in column">
                <product product="product"></product>
            </div>
        </div>
    </div>
    <div ng-hide="vm.columns && vm.columns.length">
        <div class="col-sm-12 no-products-here">
            <em>No products</em>
        </div>
    </div>
</div>

为了澄清我想添加网页现在的样子截图:http://i68.tinypic.com/1fu0ky.jpg

所需行为:列出/ api / v1 / products /

返回的所有对象

当前行为:仅列出/ api / v1 / products /返回的一个(最后一个)对象。

感谢您抽出宝贵时间阅读。 **编辑:**拼写错误

0 个答案:

没有答案