Подтвердить что ты не робот

Angular Директива JS resizable div

Мой сайт будет иметь несколько разделов, каждый из которых я намерен изменить. Для этого я сделал "изменяемую по размеру" директиву, например:

<div class="workspace" resize="full" ng-style="resizeStyle()">
<div class="leftcol" resize="left" ng-style="resizeStyle()">

С директивой, которая выглядит примерно так:

lwpApp.directive('resize', function ($window) {
    return {
        scope: {},

        link: function (scope, element, attrs) {
            scope.getWinDim = function () {
                return {
                    'height': window.height(),
                    'width': window.width()
                };
            };

            // Get window dimensions when they change and return new element dimensions
            // based on attribute
            scope.$watch(scope.getWinDim, function (newValue, oldValue) {
                scope.resizeStyle = function () {
                    switch (attrs.resize) {
                    case 'full':
                        return {
                            'height': newValue.height,
                            'width': (newValue.width - dashboardwidth)
                        };

                    case 'left':
                        return {
                            'height': newValue.height,
                            'width': (newValue.width - dashboardwidth - rightcolwidth)
                        };

                    etc...
                };
            }, true);

            //apply size change on window resize
            window.bind('resize', function () {
                scope.$apply(scope.resizeStyle);
            });
        }
    };
});

Как вы можете видеть, это только изменяет размер каждого div при изменении размера окна, и каждая директива имеет область выделения. Это отлично работает для того, для чего он создан, но в конечном итоге я хотел бы сделать подмножество divs, изменяемое по размеру, с помощью перетаскиваемого бара. Например,

div1     div2
----------------
|     ||       |
|     ||       |
|     ||       |
|     ||       |
----------------
    draggable bar in middle

При перемещении перемещаемого бара (в горизонтальном направлении) мне нужно будет получить доступ к обоим div1, div2, предположительно, через область родительского контроллера (?). Мои вопросы:

  • Является ли это "правильным" способом сделать изменяемые размеры div в angular? В частности, когда размер одного div влияет на другой?

  • Мне лично кажется, что ответ на (1): "Нет, я не делаю это правильно, потому что я не могу общаться между директивами, когда у каждого есть область выделения". Если это так, как я могу учесть как изменение размера окна, так и перетаскивание между divs?

4b9b3361

Ответ 1

Этот вопрос старый, но для любого, кто ищет решение, я создал простую директиву для этого, для вертикальных и горизонтальных resizers.

Взгляните на Plunker

enter image description here

angular.module('mc.resizer', []).directive('resizer', function($document) {

    return function($scope, $element, $attrs) {

        $element.on('mousedown', function(event) {
            event.preventDefault();

            $document.on('mousemove', mousemove);
            $document.on('mouseup', mouseup);
        });

        function mousemove(event) {

            if ($attrs.resizer == 'vertical') {
                // Handle vertical resizer
                var x = event.pageX;

                if ($attrs.resizerMax && x > $attrs.resizerMax) {
                    x = parseInt($attrs.resizerMax);
                }

                $element.css({
                    left: x + 'px'
                });

                $($attrs.resizerLeft).css({
                    width: x + 'px'
                });
                $($attrs.resizerRight).css({
                    left: (x + parseInt($attrs.resizerWidth)) + 'px'
                });

            } else {
                // Handle horizontal resizer
                var y = window.innerHeight - event.pageY;

                $element.css({
                    bottom: y + 'px'
                });

                $($attrs.resizerTop).css({
                    bottom: (y + parseInt($attrs.resizerHeight)) + 'px'
                });
                $($attrs.resizerBottom).css({
                    height: y + 'px'
                });
            }
        }

        function mouseup() {
            $document.unbind('mousemove', mousemove);
            $document.unbind('mouseup', mouseup);
        }
    };
});

Ответ 2

Я знаю, что я немного опаздываю на вечеринку, но я нашел это и нуждался в собственном решении. Если вы ищете директиву, которая работает с flexbox и не использует jquery. Я бросил вместе здесь:

http://codepen.io/Reklino/full/raRaXq/

Просто укажите, с какими направлениями вы хотите изменить размер элемента, и используете ли вы flexbox (по умолчанию - false).

<section resizable r-directions="['right', 'bottom']" r-flex="true">

Ответ 3

Для нужд моего проекта я добавил поддержку минимальных значений, чтобы панели могли сохранять некоторую ширину или высоту - (вот суть) - Github

Кроме того, я создал Github repo, где я добавил поддержку панелей, расположенных справа от оси главной страницы и поддерживающих минимальные/максимальные значения. Это сейчас на примере, но я готов превратить его в полномасштабную директиву Angular

Ответ 4

Это не полностью отвечает на вопрос, но изменение scope: true решило проблему с изоляцией. В частности, в моем html я:

<div ng-controller="WorkspaceCtrl">
  <div class="workspace" resize="full" ng-style="resizeStyle()">
    <div class="leftcol" resize="left" ng-style="resizeStyle()">
      <ul class="filelist">
        <li ng-repeat="file in files" id={{file.id}} ng-bind=file.name></li>
      </ul>
      <div contenteditable="true" ng-model="content" resize="editor" ng-style="resizeStyle()">
        Talk to me
      </div>
    </div>
</div>

и ng-repeat="file in files" все еще имеют доступ к массиву $scope.files, определенному в контроллере WorkspaceCtrl. Таким образом, scope: {} отключает область действия директивы от области родительского контроллера, тогда как scope: true просто создает новую область для каждого экземпляра директивы. Каждый экземпляр директивы вместе со своими дочерними элементами сохраняет доступ к родительский охват.

Я еще не реализовал перетаскиваемый бар, который изменяет размеры этих div, но будет отчитываться, когда я это сделаю.