我有this plunker代码。
我尝试做的是每行显示一次灰色框。
为了达到这个目的,我想修改partition
过滤器,以便返回一个JSON,按行添加一个新属性,以了解是否扩展了灰色框。
但是,我无法成功返回JSON。
您知道如何修改过滤器以返回JSON或更好的方式来逐行显示灰色框吗?
相关问题:
更新1
通过在不修改过滤器的情况下使用行的ng-repeat的正确范围,可以很容易地解决问题,这要归功于@ m59。
http://plnkr.co/edit/eEMfI1lv6z1MlG7sND6g?p=preview
更新2
如果我尝试修改item
,则会再次调用ng-repeat
而失去props
值。
<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;
};
这会导致每次修改item
时灰色框都会折叠。任何线索?
答案 0 :(得分:3)
我已更新my code/answer regarding partitioning data。在决定项目方法之前,充分理解所有这些是非常重要的。
您在plnkr
演示中遇到的问题是,您正在修改父级$scope
,而不是该行的ng-repeat的scope
。
只需在行上设置一个标志,并在点击时切换它:
<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>
要在控制器中的某个功能中访问正确的scope
,您可以使用this
关键字代替$scope
。 this
将引用调用函数的作用域,而$scope
引用带有ng-controller
的元素附加的作用域(您想要的ng-repeat
作用域的父作用域靶)。
<div
class="row"
ng-repeat="friendRow in friends | partition:2"
ng-click="collapse()"
>
JS:
$scope.collapse = function() {
this.isExpanded = !this.isExpanded;
};
如果你想在ng-click
元素上保留item
指令而不是像我一样把它放在row
元素上,那么你要处理另一个子范围,因为那个内在的ng-repeat
。因此,您需要遵循“点”规则,以便子范围可以更新collapse
指令所在的父范围。这意味着您需要在对象中嵌套isExpanded
。在此示例中,我使用ng-init="props = {}"
,然后使用props.isExpanded
。点规则有效,因为子节点共享对props
的相同对象引用,因此属性是共享的而不是仅仅复制,就像在普通的JavaScript对象引用中一样。
<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;
};
我们一直在处理越来越多的项目问题。你真的只需要进行实验/研究并理解在更深层次上发生的一切,或者只是一个接一个的问题。我会尽最大努力让你走上正轨,但你需要尝试基本概念并从那里开始。
通过props
放置$scope.expandedStates
然后将当前ng-repeat的$index
传递给您的函数来解决expandedStates
重新初始化的问题。只在视图中使用它并设置$scope.expandedStates[$index] = !$scope.expandedStates[$index]
的属性,如ng-repeat
。使用嵌套的$parent.$index
,您需要执行this
,以便将状态与行而不是项目相关联。
但是,您将遇到过滤器的另一个问题:使用旧的分区代码,每次键入字符时,分区内的输入都将失去焦点。使用新代码,视图会更新,但基础模型不会更新。您可以使用this answer中的分区过滤器来解决此问题,但根据我对该代码的理解,它可能会有一些意外的行为,并且还需要将$scope.partitionedFriends = partitionFilter($scope.friends, 2);
$scope.$watch('partitionedFriends', function(val) {
$scope.friends = [].concat.apply([], val);
}, true); // deep watch
作为参数传递给过滤器。我不建议你这样做。
过滤器意味着幂等,因此通过某种记忆来稳定它们在技术上是一种黑客攻击。有些人认为你根本不应该这样做,但我认为这很好。但是,当你出于显示目的而不是用户输入时,你肯定应该这样做!因为您在分区视图中接受用户输入,所以我建议在控制器中对数据进行分区,然后将其与手表(连续)或需要提交时一起重新连接。
{{1}}