2017-02-20 46 views
2

我是Angular begginer,正在研究一个允许对书籍进行评分的简单应用程序。曾经尝试将功能插入组件内的控制器时遇到此问题。该函数应该增加'喜欢'的数字,并在类'喜欢'的段落中显示它。但是,当我添加ng-click函数时,它似乎在改变之前元素的值(例如,当我点击元素1上的'喜欢',喜欢元素0中的计数器改变时)。你可以看看并提出可能的错误吗?Angular - 组件中的功能无法正常工作ng-repeat

以下是部分:

angular. 
module('booksList'). 
component('booksList', { 
    templateUrl: 'books-list/books-list.template.html', 
    controller: function BooksListController() { 
     this.products = [ 
      { 
       name: 'The Book of Trees', 
       price: 19, 
       pubdate: new Date('2009', '03', '08'), 
       cover: 'https://images-na.ssl-images-amazon.com/images/I/61EQH6%2BCpuL._SX376_BO1,204,203,200_.jpg', 
       likes: 0, 
       dislikes: 0 
      }, 
      { 
       name: 'Program or be Programmed', 
       price: 8, 
       pubdate: new Date('2013', '08', '01'), 
       cover: 'https://images-na.ssl-images-amazon.com/images/I/41dKoLBVToL._SX362_BO1,204,203,200_.jpg', 
       likes: 0, 
       dislikes: 0 
      }, 
      { 
       name: 'Sacred Games', 
       price: 40, 
       pubdate: new Date('2011', '09', '02'), 
       cover: 'https://images-na.ssl-images-amazon.com/images/I/51MQoLSldhL._SX327_BO1,204,203,200_.jpg', 
       likes: 0, 
       dislikes: 0 
      }, 
      { 
       name: 'Shantaram', 
       price: 20, 
       pubdate: new Date('2010', '08', '02'), 
       cover: 'https://images-na.ssl-images-amazon.com/images/I/51GEFhAifOL._SX332_BO1,204,203,200_.jpg', 
       likes: 0, 
       dislikes: 0 

      } 
     ];   
     this.orderProp = 'name';   
     this.plusOne = function(index) {    
      this.products[index].likes += 1; 
      console.log(this.products[index].likes);    
     } 
    } 
}); 

这里是我在使用功能HTML模板:

<div ng-repeat="product in $ctrl.products | filter:$ctrl.query | orderBy:$ctrl.orderProp"> 
    <div class="thumbnail"> 
     <img ng-src="{{product.cover}}" alt="{{product.name}}"> 
     <p class="title">{{ product.name }}</p> 
     <p class="price">{{ product.price | currency }}</p> 
     <p class="date">{{ product.pubdate | date }}</p> 
     <div class="rating"> 
      <p class="likes" ng-click="$ctrl.plusOne($index)">+{{product.likes}}</p> 
      <p class="dislikes" ng-click="$ctrl.minusOne()">-{{product.dislikes}}</p>    
     </div> 
    </div> 
</div> 
+0

你可以在一个蹲/小提琴重新创建这个,因为目前我看不到一个问题,只是看着它... –

+3

而不是传递产品。它更容易,更容易混淆。 –

+2

当您渲染数组时,您正在过滤并重新排序数组,这意味着'$ index'与'products'数组中的对象索引不同。 – Titus

回答

2

相反指数,

ng-click="$ctrl.plusOne($index)" 

通产品本身

ng-click="$ctrl.plusOne(product)" 

和重写功能如下

this.plusOne = function(product) {    
     product.likes += 1; 
     } 
+0

谢谢!这样可行。你能解释一下为什么它不适合索引吗?我检查了项目有适当的索引,所以这是相当令我困惑 – Joanna

+0

@Joanna,请看看我的答案。 –

+0

@joanna它的过滤导致了我认为的问题。你可以参考https://www.youtube.com/watch?v=MzqkIZLkBsU&list=PL6n9fhu94yhWKHkcL7RJmmXyxkuFB3KSl&index=6了解'$ index'是如何工作的 –

1

看来你忘了,包括track by $index

track by $index用于将您的数据与ng-repeat所做的DOM生成(主要是重新生成)链接。

在你的情况下$index是一个identity密钥,以区分你的array中的items

如果您没有唯一的标识符,track by $index也可以提供性能提升。

这是working solution

+1

我认为这并不完全代表我的问题,因为当我只有一个控制器时它工作正常(当我在你的例子中引用$ scope)。但是,当我把控制器放在组件中,然后在站点中只使用组件(带有html模板)时,索引没有正确更改。我认为这个问题可能是由上面提到的Titus过滤和重新排序引起的。 – Joanna

+1

是的,这是问题所在。另一种解决方案是为每个产品分配一个“id”属性。 –