web-dev-qa-db-fra.com

Angular div redimensionnable

Mon site comportera plusieurs sections, chacune de celles-ci devant être redimensionnable. Pour ce faire, j'ai créé une directive "redimensionnable", par exemple:

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

Avec une directive qui ressemble à quelque chose comme:

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);
            });
        }
    };
});

Comme vous pouvez le constater, cela ne fait que redimensionner chaque div lors du redimensionnement de la fenêtre, et chaque directive a une portée isolée. Cela fonctionne bien pour ce pour quoi il est construit, mais au final, je voudrais faire un sous-ensemble des div redimensionnable via une barre déplaçable. Par exemple

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

Sur le mouvement de la barre déplaçable (dans la direction horizontale), il me faudrait accéder aux largeurs de div1, div2 probablement via la portée d'un contrôleur parent (?). Mes questions sont:

  1. Est-ce la manière "correcte" de faire des divs redimensionnables en angulaire? En particulier, quand la taille d'une div en affecte une autre?

  2. Personnellement, j’ai l’impression que la réponse à (1) est "Non, je ne le fais pas correctement car je ne peux pas communiquer entre les directives lorsque chacune a une portée isolée." Si cela est vrai, comment puis-je tenir compte à la fois de la fenêtre et du redimensionnement déplaçable entre divs?

44
jayflo

Cette question est ancienne, mais pour quiconque cherchant une solution, j'ai construit une directive simple pour gérer cela, pour les redimensionneurs verticaux et horizontaux.

Regarde le 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);
        }
    };
});
95
Mario Campa

Je sais que je suis un peu en retard à la fête, mais j'ai trouvé cela et j'avais besoin de ma propre solution. Si vous recherchez une directive qui fonctionne avec flexbox et n'utilise pas jquery. J'en ai jeté un ensemble ici:

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

Déclarez simplement les directions dans lesquelles vous souhaitez redimensionner l'élément et indiquez si vous utilisez ou non flexbox (la valeur par défaut est false).

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

Pour les besoins de mon projet, j’ai ajouté le support des valeurs minimales, afin que les panneaux puissent conserver une largeur ou une hauteur voici le Gist) - --- (Github

De plus, j’ai créé rapport Github , où j’ai ajouté le support pour les panneaux situés à droite de l’axe principal de la page et le support des valeurs minimum/maximum. C’est un exemple en ce moment, mais je suis prêt à en faire un plein poids Angular angulaire

3
n3u3w3lt

Cela ne répond pas complètement à la question, mais change scope: true _ a résolu le problème de la portée isolée. En particulier, dans mon HTML j'ai:

<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>

et ng-repeat="file in files" a toujours accès au tableau $scope.files défini dans le contrôleur WorkspaceCtrl. Alors scope: {} coupe le champ d’application de la directive du champ du contrôleur parent, alors que scope: true crée simplement une nouvelle portée pour chaque instance de la directive ET chaque instance de la directive, ainsi que ses enfants, conserve l'accès à la portée parent.

Je n'ai pas encore implémenté la barre déplaçable qui redimensionne ces div, mais je ferai un rapport lorsque je le ferai.

0
jayflo