将整个子指令移动到新位置

时间:2014-09-26 12:05:15

标签: angularjs angularjs-directive angularjs-scope

我创建两个Angular指令作为一种特殊的列表。一个是父级,其他是列表中的项目。我遇到的问题是,其中一个子项必须从列表中提取出来,显示在父级内部的顶部。

但我不知道如何将整个指令/ $ scope移动到DOM中的新位置。 DropDown收集所有可用的子节点,将其中一个作为主要子节点,然后列出其余的子节点。但我只能转发整个内容。 (不会在其余部分放置<li>个标签,理想情况下它也应该这样做,所以我也希望控制它们的位置)

我已经提供了我在下面尝试完成的简短版本;理想情况下,我应该能够控制下拉列表模板中呈现的每个dd-item指令的位置。我尝试使用模板函数,但它似乎无法访问其子节点,也无法访问$ scope。

<dropdown>
  <dd-item href="#test1">Name</dd-item>
  <dd-item href="#test2">Name2</dd-item>
  <dd-item href="#test3">Name3</dd-item>
</dropdown>

angular.module('x').directive('ddItem', function () {
    return {
        restrict: 'E',
        require: '^dropdown',
        scope: {
        },
        transclude: true,
        template: '<a ng-transclude></a>',

        compile: function( $element, $attr) {
            return function ($scope, $element, $attr, dropdown) {                    
                dropdown.addItem($scope);
            }
        }

    }
})


angular.module('x').directive('dropdown', function () {
    return {
        restrict: 'E',
        scope: {},
        transclude: true,
        template: '<div><button>' +
            'the main element should be here...' +
            '</button>' +            
            '<ul><li ng-repeat="item in items"></li></ul>', // this will not work either, as I do not know how to render the whole element here
        link: function ($scope, $element, $attr) {
        },
        controller: function ($scope, $timeout) {

            $scope.main = false;
            var items = $scope.items = [];           

            this.addItem = function (item, title) {
                if (!$scope.main) {
                    $scope.main = item;
                }
                else {
                    items.push(item);
                }
            }
        }

    }
})

这个例子的预期结果应该是这个。但是这三个元素中的每一个仍然应该是一个dd-item指令,所以简单地输出html并不是一个解决方案。稍后会在dd项目中添加更多行为。

<div>
  <button>
    <a href="#test1">Name</a>
  </button>
  <ul>
    <li><a href="#test2">Name2</a></li>
    <li><a href="#test3">Name3</a></li>
  </ul>
</div>

1 个答案:

答案 0 :(得分:0)

也许您应该使用单个指令,下拉列表尝试此操作 - 然后提供控制器范围中的项目列表。

通过点击某个项目,您基本上将该项目设置为&#34;主要项目&#34;你的按钮必然会被绑定。

你确定你的下拉需要转换吗?因为您可能希望在单个页面/控制器上有多个下拉列表,并且隔离的作用域将为您提供此功能。

看看这个plunkr; http://plnkr.co/edit/xK4qdjmE0BErdID2xTIH

.directive('dropdown', function() {
      return {
        restrict: 'E',
        scope: {
          items: '=items'
        },
        // transclude: true, // i don't think you need this
        template: '<div><button ng-click="firstItem.func(message)">Main Element: {{firstItem.name}}</button>' +
          '<ul><li ng-repeat="item in items" ng-click="makeFirst(item)">{{item.name}}</li></ul>',
        link: function($scope, $element, $attr) {},
        controller: function($scope, $timeout) {
          $scope.firstItem = $scope.items[0];
          $scope.message = "hi from dropdown";
          $scope.makeFirst = function(item) {
            $scope.firstItem = item;
          };

          $scope.addItem = function(item, title) {
            items.push(item);
          };
        }
      }

<dropdown data-items="items">
</dropdown>