感谢您抽出宝贵时间阅读/提供反馈。这将是一个很长的帖子。
我最近完成了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 /返回的一个(最后一个)对象。
感谢您抽出宝贵时间阅读。 **编辑:**拼写错误