web-dev-qa-db-ja.com

ボタンを基準にしてAngularマテリアルパネルダイアログを配置するにはどうすればよいですか?

Githubでのディスカッション によると、 標準ダイアログapi )を配置することはできませんが、 パネルダイアログ (- api )を配置できます。

簡略化されたデモ は、これが正しいことを示しています。

_var position = this._mdPanel.newPanelPosition().bottom(0).right(0);
_

Angular Material docs は、クリックされた要素(または渡されたもの)を基準にして配置できるメソッドを示しています。ただし、これを機能させることはできません。

_var target = el.target;
var position = this._mdPanel.newPanelPosition().relativeTo(target); 
_

たとえば、.top().right()にハード値を渡すと、ビューポートを基準にして配置できます。ただし、クリックした要素を基準にして位置を取得することはできません。これはどのように機能するはずですか?

15
isherwood

私は過去数か月間Angular資料を扱ってきましたが、まだドキュメントが不足しているので、この問題に関する疑似ドキュメントとしてこの投稿の長さを許してください。しかし、これが私が行うことです。知っている:

addPanelPosition関数をrelativeTo関数にチェーンすることによってのみ、ターゲット要素に対してパネルの位置を機能させることができました。

var position = this._mdPanel
  .newPanelPosition()
  .relativeTo(ev.target)
  .addPanelPosition('align-start', 'below') // or other values

(この場合、evはng-clickによって渡される$ eventオブジェクトです)

addPanelPositionの許容可能なパラメーターを追跡することができましたが、それらは次のとおりです。

パネルyの位置は、次の値のみを受け入れます。アライントップス|アラインボトムス|上記|未満

Panel x Positionは、次の値のみを受け入れます。アラインスタート|アラインエンド|オフセット開始|オフセットエンド

興味深いことに、Angular Materialデモでは、this._mdPanel.xPosition.ALIGN_STARTプロパティとthis._mdPanel.yPosition.BELOWプロパティを使用して、addPanelPosition関数。私は常に文字列値を使用してきました。ただし、この機能の開発がまだ流動的であり、許容可能な文字列値が変更される場合、文字列値の使用は問題になる可能性があります。

私が見たもう1つの問題を指摘します。

デモで使用するもう1つのトリックは、ターゲット要素の代わりにrelativeTo関数でクラス名を指定し、そのクラスをターゲット要素自体に配置することです。このアプローチが役立つ理由は、ng-clickの$ eventオブジェクトが、正確にクリックされたものに基づいて異なるターゲット要素を提供できるためです。たとえば、ボタン<div>をクリックすると、ボタン内の<span>テキストをクリックした場合とは異なるターゲットが表示されます。これにより、追加の機能を提供しない限り、パネルの位置が移動します。

Codepen

私は彼らのデモを取り、この問題に焦点を合わせるために実際にサイズを縮小しました。あなたは更新されたcodepenを見ることができます ここ

5

コメントで投稿すると、 ここ プランカーで動作していることがわかります。

私の解決策は@に非常に近いです私は答えをコード化できると思います。しかし、私の答えでは、メニューの代わりに、<md-dialog>は、OPで要求されているように、ボタンがクリックされると表示されます。

ダイアログ付きの作業プランカー以外に、良い@Iに追加することはあまりありません。私は答えをコーディングできると思います。 angle-material md-panel demo に示されているように、ここで重要なのは、ボタンに対するパネルの位置を設定することです。これを行うには(angular-materialデモのように)、特定のcssクラス(demo-dialog-open-button私の例では)ターゲット要素を見つけます。これは私の意見ではトリッキーなことです...しかし、このユースケースではうまく機能します(他の回答でもよく説明されています)。

参照用のコード。詳細については、 plunker を参照してください。

html(ボタンに追加されたcssクラスに注意してください):

<md-button class="md-primary md-raised demo-dialog-open-button" ng-click="ctrl.showDialog($event)">
   Dialog 
</md-button>

[〜#〜] js [〜#〜]コントローラー。

var position = this._mdPanel.newPanelPosition()
      .relativeTo('.demo-dialog-open-button')
      .addPanelPosition(this._mdPanel.xPosition.ALIGN_START, this._mdPanel.yPosition.BELOW);

それが役に立てば幸い

1
troig

ダイアログは非常にシンプルなウィジェットです。トラッピングフォーカスは、彼らが行う最も複雑なことについてです。あなたの問題がそのような複雑な問題に発展したことは私を苦しめます。

明白なことを言うと、構成されたクラス名のおかげで、個々のダイアログの配置を完全に制御できます。

.demo-dialog-example {
    top: 20px;
    left: 20px;
}

また、showDialogメソッドで、openメソッドのpromiseを介してコールバックを設定してみませんか?何かのようなもの:

this._mdPanel.open(config).then(function() {
    var dialog = angular.element(document.querySelector('.demo-dialog-example'));
    //Centering, positioning relative to target, or draggable logic goes here
});

プラグインのロジックを改善し、「角度のある方法」で物事を実行しようとしていることを尊重しますが、これらの比較的単純な要件がそれほどの心痛を引き起こしてはなりません。

0
cage rattler