angular 指令使用全局开关操作 ngRepeat 项目
angular directive manipulating ngRepeat items with global switch
所以,我脑海中出现了以下画面:
新指令 compactList
适用于包含执行以下操作的 ngRepeat
指令的元素:
<li ng-repeat="for item in items" compact-list limit-to="3">{{item}}</li>
指令的作用:
- 给定的限制(在上例中:3)应将显示的条目限制为最多 3 个项目
- 将鼠标悬停在(鼠标悬停)任何可见项目上时,列表的其余部分也将显示(展开)
- 在鼠标移出时,其他项目将再次隐藏 - 3 个项目仍然可见
因此,从用户的角度来看,重点是拥有一个可能很长的只读列表。为了不弄乱我的布局,我想将列表限制为几个条目。只有当用户将鼠标悬停在压缩列表上时,它才会展开。天哪,多么好的功能!
从技术角度来看,这是我的基本概念:
- 指令
compactList
有一个 priority > 1000
,因此在 ng-repeat
之前执行。它通过根据 $index
添加 CSS classes 以及添加鼠标悬停和鼠标移开事件 来操纵列表项模板
- 当
ng-repeat
执行时,被操纵的列表模板会为每个带有$index < limitTo
的模板实例添加一个"hide item"CSSclass
- 必须有全局开关(
collapsed=false/true
)
- 鼠标悬停时,指令全局开关
collapsed
设置为 false,例如ngClass
将显示隐藏的项目。也就是说,列表是 "expanded"
- 在 mouseout 上,指令全局开关
collapsed
再次设置为 true。通过 ngClass
技巧,项目 4...n 将再次被隐藏
我设法通过操作模板来完成任务。但是我没能为 "directive-global switch" 想出一个像样的解决方案。我可以使用什么 Angular 机制将这样的变量附加到 compactList
指令,并且只有一个实例对所有 ng-repeat
项有效?但是,它不能是 "really" 全局的,因为同一页上可能有多个 compactList 指令。所以,只对指令的 "scope" 全局。我在括号中写了范围,因为 ngRepeat
创建了 多个范围 所以我不确定 "parent scope" 实际在哪里。
由于 ngRepeat
对 <li>
项目进行操作,这些项目相乘而不是 <ul>
标签,在我看来,将指令 compactList
放在与 ngRepeat 相同的级别可能太深了一层。也许父元素必须配备这样的变量?但这听起来不太优雅。
有人知道如何解决这个问题吗?注意:我绝对不是在寻找一些骇人听闻的解决方案。我想知道如何以优雅的 Angular-conform 方式做到这一点。我希望看到我的代码的人会惊叹而不是惊叹 ;)
在这个 plunker 中得到了一个很好的解决方案:
这是一个包含两个“列表”项的示例。
<div ng-repeat="list in lists">
<div ng-mouseleave="list.expand = false" ng-mouseover="list.expand = true" ng-repeat="item in list">
<div ng-if="$first">
List n° {{listIndex}}
</div>
<div ng-show="$index < 3 || list.expand">
{{item.value}}
</div>
</div>
</div>
我使用 ng-mouseleave
和 ng-mouseover
将动态 属性 list.exand
设置为 true
或 false
.
值部分的显示取决于您想要的限制(可以在范围内的 var 中定义)以及列表是否应该扩展。
ng-show="$index < 3 || list.expand"
如果您认为这可以满足您的需求,请告诉我。无论如何,您需要对其进行一些调整以适应您的指令的工作方式。
如果你想帮助我集成它,请分享你的指令代码(如果你在 plunker 中放一个例子就更好了),我会尽力而为。
希望对您有所帮助
编辑:
我花了一些时间来实现这个指令,就在这里。
查看此plunker
中的用途
我想出了两个应该像这样使用的指令:
<div ng-repeat="(listIndex,list) in lists">
<div compact-list>
<div ng-click="getClExpand()" ng-repeat="item in list">
<div ng-if="$first">
List n° {{listIndex}}
</div>
<div limit-to="2">
{{item.value}}
</div>
</div>
</div>
</div>
compact-list
指令添加了ng-mouseenter
、ng-mouseleave
指令。
limit-to
根据你给的号码加上ng-show
compact-list
指令
app.directive('compactList', function ($compile) {
return {
restrict: 'A',
controller:function($scope){
$scope.clExpand = false;
},
replace: false,
link: function link(scope,element, attrs) {
//don't forget to remove the directive before the compile to avoid infinite digests.
element.removeAttr("compact-list");
element.attr("ng-mouseenter","clExpand = true");
element.attr("ng-mouseleave","clExpand = false");
$compile(element)(scope);
}
};
});
limit-to
指令:
app.directive('limitTo', function ($compile) {
return {
restrict: 'A',
replace: false,
//You can't use limit-to withouth compact-list
require:"^^compactList",
link: function link(scope,element, attrs) {
element.attr("ng-show","$index < "+attrs.limitTo+" || clExpand");
//don't forget to remove the directive before the compile to avoid infinite digests.
element.removeAttr("limit-to");
$compile(element)(scope);
}
};
});
加号:您可以通过将 limit-to 指令放置在您想要的任何位置来选择要隐藏项目的哪一部分。 (如果你想隐藏物品的描述,把它放在描述div,如果你想隐藏整个物品,把它放在整个物品div。)
希望对您有所帮助。
编辑:
(作者:andimeier)
将scope=true
属性 添加到compact-list
指令中,它仍然更好(请参阅下面我的评论)。因此,compact-list
将是:
compact-list
指令
app.directive('compactList', function ($compile) {
return {
restrict: 'A',
scope: true,
controller:function($scope){
$scope.clExpand = false;
},
replace: false,
link: function link(scope,element, attrs) {
//don't forget to remove the directive before the compile to avoid infinite digests.
element.removeAttr("compact-list");
element.attr("ng-mouseenter","clExpand = true");
element.attr("ng-mouseleave","clExpand = false");
$compile(element)(scope);
}
};
});
所以,我脑海中出现了以下画面:
新指令 compactList
适用于包含执行以下操作的 ngRepeat
指令的元素:
<li ng-repeat="for item in items" compact-list limit-to="3">{{item}}</li>
指令的作用:
- 给定的限制(在上例中:3)应将显示的条目限制为最多 3 个项目
- 将鼠标悬停在(鼠标悬停)任何可见项目上时,列表的其余部分也将显示(展开)
- 在鼠标移出时,其他项目将再次隐藏 - 3 个项目仍然可见
因此,从用户的角度来看,重点是拥有一个可能很长的只读列表。为了不弄乱我的布局,我想将列表限制为几个条目。只有当用户将鼠标悬停在压缩列表上时,它才会展开。天哪,多么好的功能!
从技术角度来看,这是我的基本概念:
- 指令
compactList
有一个priority > 1000
,因此在ng-repeat
之前执行。它通过根据$index
添加 CSS classes 以及添加鼠标悬停和鼠标移开事件 来操纵列表项模板
- 当
ng-repeat
执行时,被操纵的列表模板会为每个带有$index < limitTo
的模板实例添加一个"hide item"CSSclass
- 必须有全局开关(
collapsed=false/true
) - 鼠标悬停时,指令全局开关
collapsed
设置为 false,例如ngClass
将显示隐藏的项目。也就是说,列表是 "expanded" - 在 mouseout 上,指令全局开关
collapsed
再次设置为 true。通过ngClass
技巧,项目 4...n 将再次被隐藏
我设法通过操作模板来完成任务。但是我没能为 "directive-global switch" 想出一个像样的解决方案。我可以使用什么 Angular 机制将这样的变量附加到 compactList
指令,并且只有一个实例对所有 ng-repeat
项有效?但是,它不能是 "really" 全局的,因为同一页上可能有多个 compactList 指令。所以,只对指令的 "scope" 全局。我在括号中写了范围,因为 ngRepeat
创建了 多个范围 所以我不确定 "parent scope" 实际在哪里。
由于 ngRepeat
对 <li>
项目进行操作,这些项目相乘而不是 <ul>
标签,在我看来,将指令 compactList
放在与 ngRepeat 相同的级别可能太深了一层。也许父元素必须配备这样的变量?但这听起来不太优雅。
有人知道如何解决这个问题吗?注意:我绝对不是在寻找一些骇人听闻的解决方案。我想知道如何以优雅的 Angular-conform 方式做到这一点。我希望看到我的代码的人会惊叹而不是惊叹 ;)
在这个 plunker 中得到了一个很好的解决方案:
这是一个包含两个“列表”项的示例。
<div ng-repeat="list in lists">
<div ng-mouseleave="list.expand = false" ng-mouseover="list.expand = true" ng-repeat="item in list">
<div ng-if="$first">
List n° {{listIndex}}
</div>
<div ng-show="$index < 3 || list.expand">
{{item.value}}
</div>
</div>
</div>
我使用 ng-mouseleave
和 ng-mouseover
将动态 属性 list.exand
设置为 true
或 false
.
值部分的显示取决于您想要的限制(可以在范围内的 var 中定义)以及列表是否应该扩展。
ng-show="$index < 3 || list.expand"
如果您认为这可以满足您的需求,请告诉我。无论如何,您需要对其进行一些调整以适应您的指令的工作方式。
如果你想帮助我集成它,请分享你的指令代码(如果你在 plunker 中放一个例子就更好了),我会尽力而为。
希望对您有所帮助
编辑:
我花了一些时间来实现这个指令,就在这里。
查看此plunker
中的用途我想出了两个应该像这样使用的指令:
<div ng-repeat="(listIndex,list) in lists">
<div compact-list>
<div ng-click="getClExpand()" ng-repeat="item in list">
<div ng-if="$first">
List n° {{listIndex}}
</div>
<div limit-to="2">
{{item.value}}
</div>
</div>
</div>
</div>
compact-list
指令添加了ng-mouseenter
、ng-mouseleave
指令。
limit-to
根据你给的号码加上ng-show
compact-list
指令
app.directive('compactList', function ($compile) {
return {
restrict: 'A',
controller:function($scope){
$scope.clExpand = false;
},
replace: false,
link: function link(scope,element, attrs) {
//don't forget to remove the directive before the compile to avoid infinite digests.
element.removeAttr("compact-list");
element.attr("ng-mouseenter","clExpand = true");
element.attr("ng-mouseleave","clExpand = false");
$compile(element)(scope);
}
};
});
limit-to
指令:
app.directive('limitTo', function ($compile) {
return {
restrict: 'A',
replace: false,
//You can't use limit-to withouth compact-list
require:"^^compactList",
link: function link(scope,element, attrs) {
element.attr("ng-show","$index < "+attrs.limitTo+" || clExpand");
//don't forget to remove the directive before the compile to avoid infinite digests.
element.removeAttr("limit-to");
$compile(element)(scope);
}
};
});
加号:您可以通过将 limit-to 指令放置在您想要的任何位置来选择要隐藏项目的哪一部分。 (如果你想隐藏物品的描述,把它放在描述div,如果你想隐藏整个物品,把它放在整个物品div。)
希望对您有所帮助。
编辑:
(作者:andimeier)
将scope=true
属性 添加到compact-list
指令中,它仍然更好(请参阅下面我的评论)。因此,compact-list
将是:
compact-list
指令
app.directive('compactList', function ($compile) {
return {
restrict: 'A',
scope: true,
controller:function($scope){
$scope.clExpand = false;
},
replace: false,
link: function link(scope,element, attrs) {
//don't forget to remove the directive before the compile to avoid infinite digests.
element.removeAttr("compact-list");
element.attr("ng-mouseenter","clExpand = true");
element.attr("ng-mouseleave","clExpand = false");
$compile(element)(scope);
}
};
});