ngClassは、cdk-drag-dropを使用した通常のクラスとは異なる動作をします

mladenbrankovic

編集2:この問題は素晴らしいCDKチームによって修正されました!


編集:これは非常に奇妙な振る舞いのように思われるので、私は今のところ公式のCDKリポジトリに問題を追加しましただし、アイデアや回避策を自由に提案してください。


さまざまな種類の要素があり、*cdkDropListドラッグするときにさまざまなプラクホルダーの高さが必要です。配列にはプロパティを持つオブジェクトがあるため、typeこれらの型をCSSクラスとして追加し、を使用して動的に追加しようとしました[ngClass]ただし、これらの動的に生成されたクラスは、「通常の」CSSクラスとして設定した場合とは動作が異なります。

これは、クラスを動的に設定するとどうなるかです。

ここに画像の説明を入力してください

プレースホルダーとdropList重なり合う要素関連するコードは次のとおりです。

example.component.ts

contentItems: ContentItem[] = [
  { type: 'text', /* more props */ },
  { type: 'text', /* more props */ },
  { type: 'image', /* more props */ }
];

example.component.html

<div *ngFor="let item of contentItems" class="editor-item" cdkDrag>
  <div [ngClass]="['dropzone-placeholder', item.type]" *cdkDragPlaceholder>
    <p>{{ 'EDITOR.INSERT HERE' | translate }}</p>
  </div>
  <app-language-tab-editor *ngIf="item.type === 'text'"></app-language-tab-editor>
  <app-image-upload *ngIf="item.type === 'image'"></app-image-upload>
</div>

example.component.scss

$dropzone-placeholder-dark: #00973B;
$dropzone-placeholder-light: #00973B0D;
$text-placeholder-height: 135px;
$image-placeholder-height: 375px;

.dropzone-placeholder {
  border: 1px dashed $dropzone-placeholder-dark;
  color: $dropzone-placeholder-dark;
  background: $dropzone-placeholder-light;

  &.text {
    height: $text-placeholder-height;
  }

  &.image {
    height: $image-placeholder-height;
  }
}

現在、2つの異なるタイプしかありませんが、目標は、後で追加するために簡単に拡張できるようにすることです。私もすでに代わりにclass="dropzone-placeholder {{ item.type }}"同様に使用しようとし[class]="'dropzone-placeholder ' + item.type"ましたが、役に立ちませんでした。

さらにテストした結果[ngClass]、変数を使用しなくても、通常はを使用しても機能しないことがわかりました使用も機能[ngClass]="['dropzone-placeholder', 'text']"しませんでした。

これは予想される動作です。

ここに画像の説明を入力してください

プレースホルダーとの要素dropListは重複せず、代わりに互いに適切に配置されます。現在、この動作はクラスを定期的に設定することによってのみ実現できますが、コードが将来乱雑に冗長になるため、HTMLを見るのはかなり不快です。

example.component.html

<div *ngFor="let item of contentItems" class="editor-item" cdkDrag>
  <div *ngIf="item.type === 'text'">
    <div class="dropzone-placeholder reorder text" *cdkDragPlaceholder>
      <p>{{ 'EDITOR.INSERT HERE' | translate }}</p>
    </div>
  </div>
  <div *ngIf="item.type === 'image'">
    <div class="dropzone-placeholder reorder image" *cdkDragPlaceholder>
      <p>{{ 'EDITOR.INSERT HERE' | translate }}</p>
    </div>
  </div>
  <app-language-tab-editor *ngIf="item.type === 'text'"></app-language-tab-editor>
  <app-image-upload *ngIf="item.type === 'image'"></app-image-upload>
</div>

クラスが従来の方法で設定されていないのに、CDKの動作が異なるのはなぜですか?そして、どうすれば上記の冗長な回避策を書かないようにできますか?

mladenbrankovic

更新:この問題はCDK-Packageでネイティブに修正され、回避策は廃止されました。


@ Achilles1515による前述のGitHubの問題に対するこの回答で指摘されているように、現在、TSファイルでパッチを適用したコードを使用する回避策があります。これをネイティブに修正するCDKの更新に確実に注意してください。

関連するコードは次のとおりです。

import { CdkDragDrop, DragRef, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component, EmbeddedViewRef} from '@angular/core';

DragRef.prototype._createPlaceholderElement = function(): HTMLElement {
  const placeholderConfig = this._placeholderTemplate;
  const placeholderTemplate = placeholderConfig
    ? placeholderConfig.template
    : null;
  let placeholder: HTMLElement;

  if (placeholderTemplate) {
    this._placeholderRef = placeholderConfig!.viewContainer.createEmbeddedView(
      placeholderTemplate,
      placeholderConfig!.context
    );
    this._placeholderRef.detectChanges(); // This is the missing line in the CDK
    placeholder = getRootNode(this._placeholderRef, this._document);
  } else {
    placeholder = deepCloneNode(this._rootElement);
  }

  placeholder.classList.add('cdk-drag-placeholder');
  return placeholder;
};

/** Creates a deep clone of an element. */
function deepCloneNode(node: HTMLElement): HTMLElement {
  const clone = node.cloneNode(true) as HTMLElement;
  const descendantsWithId = clone.querySelectorAll('[id]');
  const descendantCanvases = node.querySelectorAll('canvas');

  // Remove the `id` to avoid having multiple elements with the same id on the page.
  clone.removeAttribute('id');

  for (let i = 0; i < descendantsWithId.length; i++) {
    descendantsWithId[i].removeAttribute('id');
  }

  // `cloneNode` won't transfer the content of `canvas` elements so we have to do it ourselves.
  // We match up the cloned canvas to their sources using their index in the DOM.
  if (descendantCanvases.length) {
    const cloneCanvases = clone.querySelectorAll('canvas');

    for (let i = 0; i < descendantCanvases.length; i++) {
      const correspondingCloneContext = cloneCanvases[i].getContext('2d');

      if (correspondingCloneContext) {
        correspondingCloneContext.drawImage(descendantCanvases[i], 0, 0);
      }
    }
  }

  return clone;
}

function getRootNode(
  viewRef: EmbeddedViewRef<any>,
  _document: Document
): HTMLElement {
  const rootNode: Node = viewRef.rootNodes[0];

  if (rootNode.nodeType !== _document.ELEMENT_NODE) {
    const wrapper = _document.createElement('div');
    wrapper.appendChild(rootNode);
    return wrapper;
  }

  return rootNode as HTMLElement;
}

これを私のコードに追加すると、で奇妙な動作が修正されました[ngClass]

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

正規表現を使用したパンダ抽出関数は、「通常の」正規表現抽出とは異なる動作をしますか?

分類Dev

TypeScriptクラスの継承はES6の同等のものとは異なる動作をします

分類Dev

ラムダは匿名の内部クラスとは異なる動作をします

分類Dev

Drag&Drop>> e.getData は null を返します

分類Dev

Tensorflowcondはソースとは異なる動作をします

分類Dev

クエリパラメータを使用したAPITestは、通常のURLとは異なりますか?

分類Dev

zshのIFSはbashとは異なる動作をします

分類Dev

揮発性クラス型の破棄された値式は、揮発性組み込み型の値式とは異なる動作をします

分類Dev

jQuery AJAXは通常のフォームとは異なる動作をし、divベースのポップアップで呼び出します

分類Dev

if式の動作とBOOL式の評価は異なる動作をします

分類Dev

アクションとコントローラーで異なる認証スキームを使用したAuthorize属性の動作は何ですか

分類Dev

Androidのview.animate()は、最初の実行後に異なる動作と間違った動作をします

分類Dev

Java Httpsクライアント証明書は、ブラウザや他のツールとはまったく異なる動作をします

分類Dev

Java Httpsクライアント証明書は、ブラウザや他のツールとはまったく異なる動作をします

分類Dev

ssh上のzmv(zsh)は、シェルとスクリプトの間で異なる動作をします

分類Dev

(...)を使用して作成されたサブシェルは、bash -c '...'とは異なる動作をします。

分類Dev

ASP.NET CurrentUICultureは、タスクとWebAPIの遅延結果で異なる動作をします

分類Dev

グリースモンキーを使用した異なるonloadスクリプトは、YouTubeで異なる動作をします

分類Dev

ImmutableArray <>は、インデックス付きのネストされたSelectのArray <>とは異なる動作をします

分類Dev

Reddit json apiは、ブラウザーとnodejsリクエストを介してアクセスすると異なる動作をします

分類Dev

document.writeを使用して作成されたページでアンカーがクリックされた場合、Firefoxは他のブラウザとは異なる動作をします。回避策はありますか?

分類Dev

GrepはOnlineRegExp-Testerとは異なる動作をします

分類Dev

Flexbox、列は行とは異なる動作をします

分類Dev

dict.fromkeysのような組み込み型の関数記述子は、通常のメソッドとは異なる動作をします

分類Dev

WindowsのbashはLinuxのbashとは異なる動作をします

分類Dev

単体テストを使用した場合と単独で起動した場合のテストの動作は異なります

分類Dev

isset条件は、クリックごとに異なる動作をします

分類Dev

CPUは、2つの同一の電源プランを使用して異なる動作をします

分類Dev

Chromeでの編集は、FirefoxやEdgeとは異なる動作をします

Related 関連記事

  1. 1

    正規表現を使用したパンダ抽出関数は、「通常の」正規表現抽出とは異なる動作をしますか?

  2. 2

    TypeScriptクラスの継承はES6の同等のものとは異なる動作をします

  3. 3

    ラムダは匿名の内部クラスとは異なる動作をします

  4. 4

    Drag&Drop>> e.getData は null を返します

  5. 5

    Tensorflowcondはソースとは異なる動作をします

  6. 6

    クエリパラメータを使用したAPITestは、通常のURLとは異なりますか?

  7. 7

    zshのIFSはbashとは異なる動作をします

  8. 8

    揮発性クラス型の破棄された値式は、揮発性組み込み型の値式とは異なる動作をします

  9. 9

    jQuery AJAXは通常のフォームとは異なる動作をし、divベースのポップアップで呼び出します

  10. 10

    if式の動作とBOOL式の評価は異なる動作をします

  11. 11

    アクションとコントローラーで異なる認証スキームを使用したAuthorize属性の動作は何ですか

  12. 12

    Androidのview.animate()は、最初の実行後に異なる動作と間違った動作をします

  13. 13

    Java Httpsクライアント証明書は、ブラウザや他のツールとはまったく異なる動作をします

  14. 14

    Java Httpsクライアント証明書は、ブラウザや他のツールとはまったく異なる動作をします

  15. 15

    ssh上のzmv(zsh)は、シェルとスクリプトの間で異なる動作をします

  16. 16

    (...)を使用して作成されたサブシェルは、bash -c '...'とは異なる動作をします。

  17. 17

    ASP.NET CurrentUICultureは、タスクとWebAPIの遅延結果で異なる動作をします

  18. 18

    グリースモンキーを使用した異なるonloadスクリプトは、YouTubeで異なる動作をします

  19. 19

    ImmutableArray <>は、インデックス付きのネストされたSelectのArray <>とは異なる動作をします

  20. 20

    Reddit json apiは、ブラウザーとnodejsリクエストを介してアクセスすると異なる動作をします

  21. 21

    document.writeを使用して作成されたページでアンカーがクリックされた場合、Firefoxは他のブラウザとは異なる動作をします。回避策はありますか?

  22. 22

    GrepはOnlineRegExp-Testerとは異なる動作をします

  23. 23

    Flexbox、列は行とは異なる動作をします

  24. 24

    dict.fromkeysのような組み込み型の関数記述子は、通常のメソッドとは異なる動作をします

  25. 25

    WindowsのbashはLinuxのbashとは異なる動作をします

  26. 26

    単体テストを使用した場合と単独で起動した場合のテストの動作は異なります

  27. 27

    isset条件は、クリックごとに異なる動作をします

  28. 28

    CPUは、2つの同一の電源プランを使用して異なる動作をします

  29. 29

    Chromeでの編集は、FirefoxやEdgeとは異なる動作をします

ホットタグ

アーカイブ