angularjs repeat map和bootstrap,我有个array,里面有10个nested array,我可以用ng-repeat在屏幕尺寸为小的时候,

AngularJS: do not pass $index in ng-repeat if you use orderBy | sky2high
& Русский (Russian)
CategoriesActionscript 3 (9)Adobe Flex 3, 4 (6)Java (3)Erlang (7)Python (11)Интерфейсы (13)Юзабилити (8)Наука (13)Без рубрики (14)Javascript (5)Javascript (5)PHP (3)Zend Framework (3)Zend Framework (3)PHP (4)Sys. admin's (6)Sys. admin's (6)Мобильные телефоны и пр. (1)MySQL (2) adsjavascript - AngularJS filter:notarray error in nested ng-repeat - Stack Overflow
to customize your list.
Announcing Stack Overflow Documentation
We started with Q&A. Technical documentation is next, and we need your help.
Whether you're a beginner or an experienced developer, you can contribute.
I'm trying to list some data that I get from a DB, I have nested ng-repeat inside another ng-repeat. The problem is when I try to filter the results from a search, I get this error:
Error: [filter:notarray] Expected array but received: {}
I've tried some solutions founded here but no results...
Here is the factory who get the JSON:
angular.module('vSalesApp')
.factory('listClients', function ($http) {
list: function(callback){
$http.get('api/call/clients').success(callback);
Here is my controller:
angular.module('vSalesApp')
.controller('ClientsCtrl', function ($scope, $http, $filter, listClients) {
listClients.list(function(listClients){
$scope.clients = listC
Here is the view:
&input ng-model="somefield"&
&div class="list-group" ng-repeat="client in clients | filter:somefield"&
&button type="button" class="list-group-item active"&{{client.name}} - {{client.child_ids}}&/button&
&button type="button" class="list-group-item" ng-repeat="child pany_childs | filter:somefield"&{{child.name}}&/button&
The client object usualy look like this:
"city": false,
"name": "Company test",
"nrc": false,
"child_ids": [77],
"phone": "",
"contact_address": "Street 1\n\n \nBelgium",
"vat": false,
"bank_ids": [3],
"company_childs": [{
"city": false,
"name": "Delivery",
"zip": false,
"street2": "Delivery",
"phone": false,
"street": "Street 2",
The problem comes when company_childs is empty, like this object:
"city": "D\u00fcsseldorf",
"name": "Federal",
"nrc": false,
"child_ids": [],
"phone": false,
"contact_address": "Willi-Becker-Allee 10\n\n40227 D\u00fcsseldorf\nGermany",
"vat": false,
"bank_ids": [],
"company_childs": []
How can I manage this? I've tried ng-if or toArray:false like in the DOCS but still nothing. For each object that company_childs is empty, I get the error mentioned.
Many thanks!
edit: I have to mention that the search work properly, it filter the client and company_childs as expected.
edit2: Here is a
I have changed the API so I force PHP to create an empty JSON array:
$someArray = [];
foreach ($companies as $key) {
if ($key['child_ids'] != null){
$childs = $rpc-&read($uid, $pwd, $key['child_ids'], array('name', 'street', 'city', 'street2', 'zip', 'phone'), "res.partner"); //here I get each child
$key['company_childs'] = $
array_push($someArray, $key);
elseif ($key['child_ids'] == null) {
$key['company_childs'][] = new ArrayObject(); //If no childs, create empty array
array_push($someArray, $key);
return $app-&JsonResponse($someArray);
edit3: After the modification of my API, if I copy the JSON results and paste it in my controller, I don't get anymore the error. I really don't understand why.
angular.module('vSalesApp')
.controller('ClientsCtrl', function ($scope, $http, $filter, listClients) {
$scope.clients = [{JSON array}]
JSON lint confirm that the output of the API is an array (but empty)!
JSON output from API after JSON lint:
"city": false,
"name": "Company test",
"nrc": false,
"child_ids": [77],
"phone": "",
"contact_address": "Street 1\n\n \nBelgium",
"vat": false,
"bank_ids": [3],
"company_childs": [{
"city": false,
"name": "Delivery",
"zip": false,
"street2": "Delivery",
"phone": false,
"street": "Street 2",
"city": "Chicago",
"name": "Your Company, Chicago",
"nrc": false,
"child_ids": [73],
"phone": "+1 312 349 3030",
"contact_address": "90 Streets Avenue\n\nChicago IL 60610\nUnited States",
"vat": false,
"bank_ids": [],
"company_childs": [{
"city": "Chicago",
"name": "Steven Hamilton",
"zip": "60610",
"street2": false,
"phone": false,
"street": "90 Streets Avenue",
"city": "D\u00fcsseldorf",
"name": "Federal",
"nrc": false,
"child_ids": [],
"phone": false,
"contact_address": "Willi-Becker-Allee 10\n\n40227 D\u00fcsseldorf\nGermany",
"vat": false,
"bank_ids": [],
"company_childs": []
edit4: I added the factory who get the clients from the API
Know someone who can answer?
Share a link to this
via , , , or .
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Browse other questions tagged
Stack Overflow works best with JavaScript enabled利用Angularjs和bootstrap实现购物车功能
作者:小弋呀
字体:[ ] 类型:转载 时间:
在学习了如何简单开始一个Angular程序之后,跟着网上的教程我也来实现一个购物车功能,为了减少页面样式设计我使用了bootstrap来偷懒,现在分享给大家,有需要的可以参考借鉴。
先来看看效果图:
如果看了这个效果有兴趣想知道怎么做出来的话,那就继续往下看吧。话不多少,直接上代码。
html代码:
&!DOCTYPE html&
&html lang="en" ng-app="cart"&
&meta charset="UTF-8"&
&title&购物车&/title&
&link rel="stylesheet" href="../scripts/angular-1.4.0-rc.2/docs/components/bootstrap-3.1.1/css/bootstrap.min.css"&
&link rel="stylesheet" href="main.css"&
&body ng-controller="cartCtr"&
&table class="table table-hover" ng-show="items.length"&
&caption&AngularJS实现购物车&/caption&
&th&序号&/th&
&th&商品信息&/th&
&th&单价(元)&/th&
&th&数量&/th&
&th&金额(元)&/th&
&th&操作&/th&
&tr ng-repeat=" item in items"&
&td&{{$index + 1}}&/td&
&td&&a href="{{item.linkUrl}}" target="_blank" title="此链接将跳转到淘宝相关页面..."&{{item.title}}&/a&&/td&
&td class="bold"&{{item.price|number:2}}&/td&
&button type="button" class="btn btn-default btn-xs" ng-click="reduce(item.id)" ng-disabled="item.quantity&=1"&-&/button&
&input type="text" size="5" ng-model="item.quantity" ng-keydown="quantityKeydown()" ng-keyup="quantityKeyup()"&
&button type="button" class="btn btn-default btn-xs" ng-click="add(item.id)"&+&/button&
&td class="bold mark"&{{item.price*item.quantity|number:2}}&/td&
&button type="button" class="btn btn-default btn-xs" ng-click="delete(item.id)"&删除&/button&
&div class="empty" ng-show="!items.length"&购物车空空,快去寻找宝贝&/div&
&div class="total"&
已选商品:&span&{{getQuantites()}} &/span&
&span class=" mark" ng-show="getTotalAmount()&15000"&{{getTotalAmount()|number:2}}&/span&
&span class=" mark" ng-show="getTotalAmount()&=15000"&
{{getTotalAmount()*discount|number:2}}&span class="btn btn-xs"&(9折)&/span&
&span class="discount"&({{getTotalAmount()|number:2}})&/span&
&button type="button" class="btn btn-primary btn-sm" ng-click="alertSubmit()"&结 算&/button&
&script src="../scripts/angular-1.4.0-rc.2/angular.js"&&/script&&script src="app.js"&&/script&
/ Created by wqq on . /
var cartModule = angular.module('cart', []);
cartModule.controller('cartCtr', ['$scope', function ($scope) {
$scope.discount = 0.9;
$scope.items = [{id: 10001,title: "Web全栈工程师的自我修养 余果", price: 40.80,quantity: 2,linkUrl: "/item.htm?spm=a1z0d..cwywJs&id="},
{id: 10002,title: "MacBook Pro Retina 15英寸", price: 16088.00,quantity: 1,linkUrl: "/item.htm?spm=a1z0d..cwywJs&id="},
{id: 10003,title: "Surface Book I5 128G 独显",price: 11088.00, quantity: 1,linkUrl: "/item.htm?spm=a1z0d..cwywJs&id="},
{id: 10004, title: "Lenovo Yoga3Pro I5 4G",price: 7299.00, quantity: 1,linkUrl: "/item.htm?spm=a1z0d..cwywJs&id="} ];
$scope.add = function (id) {
angular.forEach($scope.items, function (item, index, array) {
if (item.id === id) {item.quantity++;} })
$scope.reduce = function (id) {
angular.forEach($scope.items, function (item, index, array) {
if (item.id === id) {item.quantity--; } })
//输入框添加keydown事件,避免输入非正整数
$scope.quantityKeydown = function (event) {
event = event || window.
var target=event.target||event.srcE
var keycode = event.keyC
if ((37 &= keycode && keycode &= 40)||(48 &= keycode && keycode &= 57) || (96 &= keycode && keycode &= 105) || keycode == 8) {
//方向键↑→ ↓←、数字键、backspace
console.log(keycode);
event.preventDefault();
//keyup事件,当输入数字为0时,重新刷新文本框内容
$scope.quantityKeyup = function (event) {
event = event || window.
var target=event.target||event.srcE
var keycode = event.keyC
if (48 === keycode || 96 === keycode ) {
target.value=parseInt(target.value);
//删除商品
$scope.delete = function (id) {
$scope.items.forEach(function (item, index) {
if (item.id == id) {
if (confirm("确定要从购物车中删除此商品?")) {
$scope.items.splice(index, 1);
//计算已选商品数量
$scope.getQuantites = function () {
var quantities = 0;
angular.forEach($scope.items, function (item, index, array) {
if (item.quantity) {
quantities += parseInt(item.quantity);
//计算合计总金额
$scope.getTotalAmount = function () {
var totalAmount = 0;
angular.forEach($scope.items, function (item, index, array) {
totalAmount += item.quantity * item.
return totalA
$scope.alertSubmit = function () {alert("Angular实现购物车"); }
请忽略bootstrap的样式,我们只关注Angular,代码很简单,我们来简单的分析一下:
首先我们我们定义了一个cart模块、cartCtr控制器,并将它们引入到了html代码中,同时我们还在js中定义了一个数组items用于模拟购物车内的东西。
2. ng-repeat迭代器
为了将items里的数据动态的遍历加载出来,我们使用Angular里的内置指令ng-repeat,它可以非常方便的遍历数组,生成DOM元素,在这里循环生成了4个&tr&标签:
  &tr ng-repeat=" item in items"&
item就是items数组里面的某一个对象,是不是感觉这就是js中的for/in循环~~如果你是一名.net开发人员,用过asp.net mvc的Razor就对这种其他语言无缝操作DOM元素很熟悉了,至于java、PHP是否有没有类似的语法我就不清楚了,我是一名苦逼的.net开发。
ng-repeat迭代器
我们可以看到第一个td中用到了$index,这是ng-repeat内的,并不是我们定义的,它的值是当前item在items中的索引,从0开始,所以我们用$index+1作为序号,其他的还有(类似item.linkUrl)数据绑定。
我们在单价和金额两列用到了{{ xxx|number:2}},这是Angular中的一种过滤器,作用是将前面的值xxx保留两位小数,金额嘛,我们当然要精确一些。刚才说了这是一种过滤器,那就还有其他的,比如currency,可以在xxx前面添加一个$符号表示美元,可以自行百度其他过滤器用法。
3. 添加事件
当前界面上分别有数量+、-按钮、删除按钮,这几个事件都比较简单,利用ng-click给元素添加点击事件。通过传递某个商品的id,找到这个商品,对这个商品进行加、减、删除操作,只不过在“-”按钮上有添加了一个ng-disabled标签,根据名字我们就可以很容易想到html的disabled属性,它的作用就是当ng-disabled的值为true时DOM元素禁用,同理,下面用到的ng-show也是一样的,true时显示,false时隐藏。如果是数字的话会自动转化为boolean值,0是false,非0是true,注意负数也是true!。这里我让当数量为1时就不能减少了,因为再少就可以直接删除了呀~
然后在input元素添加ng-keydown事件,使其只能输入方向键↑→ ↓←、数字键、backspace。然后我试了下确实到达了目的,但是却可以输入类似“00021”这种数字,显然这并不能令人满意。我看了看淘宝的购物车,发现当在前面输入0时,这个文本框的内容会自动刷新,去掉前面的0,于是我又添加了ng-keyup事件:
$scope.quantityKeyup = function (event) {
event = event || window. //兼容IE8以下,target也是
var target=event.target||event.srcE
var keycode = event.keyC
if (48 === keycode || 96 === keycode ) {
target.value=parseInt(target.value);
这时当我输入0时,文本框值就会自动刷新,为什么不添加到keydown里面而要另外再加一个事件呢?那是因为触发keydown事件时target.value的值还是原来的值,还没有包含本次输入的按键,而在keydown之后值就是新值了,这时候我们接着让触发keyup事件就可以达到目的了,可以对照看下淘宝购物车的效果,我觉得我的体验比它的更好,因为它只要不是在最后输入数字文本框总是会失去焦点。。。
统计数量就是直接绑定方法,遍历数组返回值。
合计金额这块,我做了个满15000打9折的设计。利用ng-show隐藏显示带打折信息的合计金额。
js中用到了几处forEach遍历数组,ECMAScript5中原生的方法是array.forEach(function(item,index,array){});
angular中也封装了,angular.forEach(array,function(item,index,array){});
代码中我两种方法都用到了,也不知道那种性能好。。
至此,购物车就已经完成了,利用Angular的双向绑定,可以快速的实现数量、金额的联动改变。希望这篇文章的内容对大家学习和使用Angular能有所帮助,如果有疑问可以留言交流。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 angularjs的ng repeat 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信