我有一个ng-repeat指令,其中显示了所有对象(思想)。如果一个想法描述(字符串)长于x,我只想显示前x个字符和“全部显示”链接。用户可以单击此链接,然后将显示整个文本。但是一次只能显示一个想法及其全文。

我现在有这个:

div(ng-show = "idea.description.length > maxIdeaDescLength && openLongIdea != idea._id")
  i {{idea.description.substring(0, maxIdeaDescLength) }} ...
  a(href='', ng-click='openLongIdea = idea._id') show all
div(ng-show = "idea.description.length <= maxIdeaDescLength || openLongIdea == idea._id")
  i {{idea.description}}


这是我的控制器的一部分:

$scope.openLongIdea = 0;


因此,当我单击“显示全部”链接时,ideaID将保存到变量openLongIdea。并且由于我的ng-show条件,我希望仅在idea-ID与openLongIdea-ID匹配时才显示整个描述。但是我仍然一次看到不止一个想法及其详细描述。

第一次显示想法时,我的逻辑起作用了。当我单击“显示全部”链接时,将显示较长的文本。但是,当我单击另一个想法的“查看全部”链接时,尽管我用新的Idea-ID覆盖了openLongIdea中的值,但它也将整体显示在旧想法旁边。

这里有什么问题?

最佳答案

如评论中所指出的,它看起来像是绑定到原语的问题。在JavaScript中,原语(布尔值,数字,字符串)是不可变的,因此当您更改数字(例如数字maxIdeaDescLength)时,前一个实例将被丢弃,而将使用新的实例。这破坏了Angular的双向绑定,并且maxIdeaDescLength的任何其他用法都不会用新值更新。

您可以通过将openLongIdea设置为$scope上对象的属性来解决此问题。 $scope.data.openLongIdea。在这种情况下,即使$scope发生变化,data也会引用maxIdeaDescLength,因此可以访问maxIdeaDescLength的更新值。

但是,请考虑切换到controllerAs视图语法。从John Papa's style guide以及其他参数中:


  它促进了对视图中“点状”对象的绑定的使用(例如
  customer.name而不是name),因为上下文更容易理解
  阅读,并避免可能发生的任何参考问题
  “点”。


更新的控制器:

var app = angular.module("app", []);
app.controller('ctrl', function () {
  var vm = this;
  vm.maxIdeaDescLength = 10;
  vm.ideas = [
    {_id : 0, description :'abcd efgh ijkl'},
    {_id : 1, description :'qwer tyui opzx'}
  ];
});


示例视图:

<div ng-app="app" ng-controller="ctrl as vm">
  <div ng-repeat="idea in vm.ideas">
    <div ng-show = "idea.description.length > vm.maxIdeaDescLength && vm.openLongIdea !== idea._id">
      {{idea.description.substring(0, vm.maxIdeaDescLength) }}
      <a href='' ng-click='vm.openLongIdea = idea._id'> show all </a>
    </div>
    <div ng-show = "idea.description.length <= vm.maxIdeaDescLength || vm.openLongIdea === idea._id">
      {{idea.description}}
    </div>
  </div>
</div>


JsFiddle

08-17 06:25