如何使用角度js将元素移动到DOM中的不同位置?
我有一个像这样的元素列表
<ul id="list" ng-controller="ListController">
<li ng-controller="ItemController"><div>content</div></li>
<li ng-controller="ItemController"><div>content</div></li>
<li ng-controller="ItemController"><div>content</div></li>
<li ng-controller="ItemController">
<div>content</div>
<div id="overlay"></div>
</li>
</ul>
我想要完成的是将#overlay从一个地方移到另一个地方,而不必在我标记为隐藏/未隐藏的每个项目中都有隐藏的副本。
如果这是jquery我可以做这样的事情:
$("#overlay").appendTo("#list li:first-child");
是否有相同的方法在角度中执行此操作?
答案 0 :(得分:11)
感谢您的澄清,我可以理解您有一个项目列表。您希望能够在此列表中选择一个项目(滑动但可能还有其他事件),然后为所选项目显示其他DOM元素(div)。如果选择了其他项目,则应该取消选中 - 这样只有一个项目应该显示另一个div。
如果上述理解是正确的,那么您可以使用这样的简单ng-repeat和ng-show指令来解决这个问题:
<ul ng-controller="ListController">
<li ng-repeat="item in items">
<div ng-click="open(item)">{{item.content}}</div>
<div ng-show="isOpen(item)">overlay: tweet, share, pin</div>
</li>
</ul>
控制器中的代码(仅显示其片段):
$scope.open = function(item){
if ($scope.isOpen(item)){
$scope.opened = undefined;
} else {
$scope.opened = item;
}
};
$scope.isOpen = function(item){
return $scope.opened === item;
};
以下是完整的jsFiddle:http://jsfiddle.net/pkozlowski_opensource/65Cxv/7/
如果您担心有太多的DOM元素,可以使用ng-switch指令实现相同的目的:
<ul ng-controller="ListController">
<li ng-repeat="item in items">
<div ng-click="open(item)">{{item.content}}</div>
<ng-switch on="isOpen(item)">
<div ng-switch-when="true">overlay: tweet, share, pin</div>
</ng-switch>
</li>
</ul>
这是jsFiddle:http://jsfiddle.net/pkozlowski_opensource/bBtH3/2/
答案 1 :(得分:4)
作为读者(我)的练习,我想尝试一个自定义指令来实现这一目标。这是我想出的(经过多次尝试失败后):
<ul ng-controller="ListController">
<li ng-repeat="item in items">
<div singleton-overlay>{{item.content}}</div>
</li>
</ul>
需要服务来存储当前具有叠加层的元素(如果有)。 (我决定不使用控制器,因为我认为'service + directive'会产生比'controller + directive'更可重用的组件。)
service('singletonOverlayService', function() {
this.overlayElement = undefined;
})
指令:
directive('singletonOverlay', function(singletonOverlayService) {
return {
link: function(scope, element, attrs) {
element.bind('click', moveOrToggleOverlay);
function moveOrToggleOverlay() {
if (singletonOverlayService.overlayElement === element) {
angular.element(element.children()).remove();
singletonOverlayService.overlayElement = undefined;
} else {
if (singletonOverlayService.overlayElement != undefined) {
// this is a bit odd... modifying DOM elsewhere
angular.element(singletonOverlayService.overlayElement.children()).remove();
}
element.append('<div>overlay: tweet, share, pin</div>')
singletonOverlayService.overlayElement = element;
jsFiddle:http://jsfiddle.net/mrajcok/ya4De/
我认为实现有点不同寻常,但是......指令不仅修改了与其自身元素相关联的DOM,而且还可以修改与当前具有覆盖的元素相关联的DOM。
我尝试在示波器上设置$ watch并使用单例存储并修改范围对象,但是当我从moveOrToggleOverlay函数内部更改范围时,我无法触发$ watches。