如何设置一个布尔标志折叠/扩大与NG重复的行 [英] How to set a boolean flag to collapse/expand a row with ng-repeat

查看:110
本文介绍了如何设置一个布尔标志折叠/扩大与NG重复的行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 plunker code。

I have this plunker code.

我想要做的,是显示灰色框每行一次。

What I'm trying to do, is to display the gray box one time per row.

要实现这一点,我想修改分区过滤器,以返回JSON按行添加一个新的属性知道灰色框展开或没有。

To achieve this, I thought to modify the partition filter in order to return a JSON to add it a new property by row to know if the gray box is expanded or not.

不过,我无法成功返回JSON。

But, I could Not successfully return a JSON.

你知道如何修改过滤器返回一个JSON或一个更好的方式来显示由排灰框?

Do you know how to modify the filter to return a JSON or a better way to show the gray box by row?

相关问题:

  • Push down a series of divs when another div is shown

更新1

这个问题可以通过使用为NG-重复该行的正确的范围,而无需修改过滤器,感谢@ M59很容易解决的。

The issue could be easily resolved by using the correct scope for the ng-repeat for the row without modifying the filter, thanks to @m59.

http://plnkr.co/edit/eEMfI1lv6z1MlG7sND6g?p=$p$ PVIEW

更新2

现场演示

如果我试图修改项目,似乎 NG-重复将再次调用不失道具值。

If I try to modify the item, it seems the ng-repeat would be called again losing the props values.

  <div ng-repeat="friendRow in friends | partition:2" 
       ng-init="props = {}">
    <div ng-repeat="item in friendRow" 
         ng-click="collapse(item)" 
         ng-class="{myArrow: showArrow}">
      {{item.name}} {{item.age}} years old.
      <div>{{item.name}}</div>
    </div>
    <div collapse="!props.isExpanded">
      some content
      <br/>
      <input type="text" ng-model="currentItem.name">
    </div>
  </div>

JS

  $scope.collapse = function(item){
     this.props.isExpanded  = !this.props.isExpanded;
     this.showArrow = !this.showArrow;
     $scope.currentItem = item;
  };

这将导致灰色框每个项目被修改时崩溃。任何线索?

This causes the gray box to collapse each time the item is modified. Any clue?

推荐答案

我已经更新我的code /回答关于分区数据。重要的是要在一个方法决定你的项目之前,充分了解了这一切。

I've updated my code/answer regarding partitioning data. It's important to fully understand all of that before deciding on an approach to your project.

您在 plnkr 演示的问题是,你正在修改父 $范围而不是范围的NG-重复该行的。

The problem you have in your plnkr demo is that you're modifying the parent $scope and not the scope of the ng-repeat for that row.

只是设置一个标志,该行并点击时将其切换:

Just set a flag on the row and toggle it when clicked:

<div 
  class="row" 
  ng-repeat="friendRow in friends | partition:2"
  ng-init="isExpanded = false" 
  ng-click="isExpanded = !isExpanded"
>
  <div ng-repeat="item in friendRow">
    {{item.name}} {{item.age}} years old.  
  </div>
  <div collapse="!isExpanded">
    some content
  </div>
</div>

要访问的一个功能中的正确范围,您可以使用这个关键字来代替 $范围这个将参考范围函数被调用,而 $范围指连接到与元素的范围 NG-控制器(即的父NG重复作用域要目标)。

To access the correct scope within a function in the controller, you can use the this keyword instead of $scope. this will refer to the scope the function is called from, whereas $scope refers to the scope attached to the element with ng-controller (a parent of the ng-repeat scopes you want to target).

<div 
  class="row" 
  ng-repeat="friendRow in friends | partition:2" 
  ng-click="collapse()"
>

JS:

$scope.collapse = function() {
   this.isExpanded  = !this.isExpanded;
};

如果你想保持在 NG-点击指令项元素,而不是把它放在的元素,因为我已经做了,那么你要处理的,因为这里面的 NG-重复另一个孩子的范围。因此,您需要按照点规则,使孩子作用域可以更新父范围,其中崩溃指令是。这意味着你需要在一个对象巢 isExpanded 。在这个例子中,我使用 NG-的init =道具= {},然后用 props.isExpanded 。点规则的作用,因为孩子们共享相同的对象引用道具,所以属性是共享的,而不仅仅是复制,就像在普通的JavaScript对象的引用。

If you want to keep the ng-click directive on the item element instead of putting it on the row element as I have done, then you're dealing with another child scope because of that inner ng-repeat. Therefore, you will need to follow the "dot" rule so that the child scope can update the parent scope where the collapse directive is. This means you need to nest isExpanded in an object. In this example, I use ng-init="props = {}", and then use props.isExpanded. The dot rule works because the children share the same object reference to props, so the properties are shared rather than just copied, just like in normal JavaScript object references.

<div 
  class="row"
  ng-repeat="friendRow in friends | partition:2" 
  ng-init="props = {}"
>
  <div ng-repeat="item in friendRow" ng-click="collapse()">
    {{item.name}} {{item.age}} years old.
  </div>
  <div collapse="!props.isExpanded">
    some content
  </div>
</div>

JS:

$scope.collapse = function(){
   this.props.isExpanded  = !this.props.isExpanded;
};

更新

我们一直在经历着越来越多的问题,与您的项目。你真的只需要实验/研究和理解,是怎么回事更深层次的一切,否则将只是一个又一个问题。我给它最后的努力,让你在正确的轨道上,但你需要的基本概念,试图从那里。

Update

We keep going through more and more issues with your project. You really just need to experiment/research and understand everything that's going on on a deeper level, or it will just be one question after another. I'll give it one last effort to get you on the right track, but you need to try in the basic concepts and go from there.

您的 的能拿过去道具的问题通过将重新初始化 $ scope.expandedStates 然后传递 $指数给你的函数(或者只是用它在视图)和设置的属性 expandedStates $ scope.expandedStates [$指数] =!$ scope.expandedStates [$指数] 。随着嵌套的 NG-重复,因为它是,你需要做的 $父。$指数,这样你'重新状态与行相关联,而不是该项目。

You could get past the issue of props reinitializing by putting $scope.expandedStates and then passing the $index of the current ng-repeat to your function (or just using it in the view) and setting a property of expandedStates like $scope.expandedStates[$index] = !$scope.expandedStates[$index]. With the nested ng-repeat as it is, you'll need to do $parent.$index so that you're associating the state with the row rather than the item.

然而,你再有过滤器的另一个问题:用我的旧分区code,分区里面的投入将失去专注在你输入一个字符的时间。使用新的code,视图更新,但底层模型不会。你可以使用从 这个答案分区过滤器 来解决这个问题,但是从我的这种理解code,它可能有一些意外的行为的道路,同时也需要在通过这个作为参数传递给过滤器。我不建议你这么做。

However, you'll then have another problem with the filter: Using my old partition code, the inputs inside the partitions are going to lose focus every time you type a character. Using the new code, the view updates, but the underlying model will not. You could use the partition filter from this answer to solve this, but from my understanding of that code, it could have some unexpected behavior down the road and it also requires passing in this as an argument to the filter. I don't recommend you do this.

过滤器是为了幂等,通过某种记忆化,使他们稳定在技术上是一个黑客。一些人认为你永远不应该这样做,在所有的,但我认为这很好。但是,你一定要只能这样做时,它是用于显示目的,而不是用户输入!因为你是接受的分区视图中的用户输入,我建议在控制器分区中的数据,那么无论是与手表结合它重新走到一起(连续),或者当你需要提交。

Filters are meant to be idempotent, so stabilizing them via some kind of memoization is technically a hack. Some argue you should never do this at all, but I think it's fine. However, you definitely should ONLY do this when it is for display purposes and not for user input! Because you are accepting user input within the partitioned view, I suggest partitioning the data in the controller, then joining it back together either with a watch (continuous) or when you need to submit it.

$scope.partitionedFriends = partitionFilter($scope.friends, 2);

$scope.$watch('partitionedFriends', function(val) {
  $scope.friends = [].concat.apply([], val);
}, true); // deep watch

这篇关于如何设置一个布尔标志折叠/扩大与NG重复的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆