web-dev-qa-db-ja.com

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のサイズを変更するだけで、各ディレクティブには分離スコープがあります。これはその目的のためにうまく機能しますが、最終的にはドラッグ可能なバーを介してdivのサブセットをサイズ変更可能にしたいと思います。例えば

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

ドラッグ可能なバーの移動(水平方向)で、おそらく親コントローラー(?)のスコープを介して、div1、div2の両方の幅にアクセスする必要があります。私の質問は:

  1. これは角度でサイズ変更可能なdivを作成するための「正しい」方法ですか?特に、あるdivのサイズが別のdivに影響する場合は?

  2. 私は個人的に、(1)に対する答えは「いいえ、それぞれが独立したスコープを持つディレクティブ間で通信できないため、正しく実行していません」と感じています。これが当てはまる場合、divとdivの間でウィンドウとドラッグ可能なサイズ変更の両方をどのように考慮することができますか?

44
jayflo

この質問は古いものですが、解決策を探している人のために、これを処理するために、垂直および水平リサイズ用の簡単なディレクティブを作成しました。

プランカーを見てください

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

私はパーティーに少し遅れていることを知っていますが、私はこれを見つけて、独自の解決策を必要としました。フレックスボックスで動作し、jqueryを使用しないディレクティブを探している場合。私はここで一緒に投げました:

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

要素のサイズを変更する方向、およびflexbox(デフォルトはfalse)を使用しているかどうかを宣言するだけです。

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

私のプロジェクトのニーズに合わせて、最小値のサポートを追加しました。これにより、パネルがある程度の幅または高さを維持できるようになりました ここが要点です)----(Github

また、 Github repo を作成しました。ここでは、メインページの軸の右側にあるパネルのサポートと、最小値/最大値のサポートを追加しました。現在は例の段階ですが、フルウェイトAngularディレクティブに変更したいと思います

3
n3u3w3lt

これは質問に完全には答えませんが、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のサイズを変更するドラッグ可能なバーはまだ実装していませんが、そうするとレポートします。

0
jayflo