简体   繁体   English

使用 cdkDropList 时元素样式不适用(角度 cdk 拖放)

[英]Element style doesn't apply when using cdkDropList (Angluar cdk drag and drop)

I am posting this question just to answer it myself in case anyone is struggling like I did!我发布这个问题只是为了自己回答,以防有人像我一样挣扎!

I'm working on an angular project to implement a Trello-like application.我正在开发一个 angular 项目来实现类似 Trello 的应用程序。 I want to be able to drag an element from one list to another so I installed the Angular cdk module and followed their guide .我希望能够将一个元素从一个列表拖到另一个列表,所以我安装了 Angular cdk 模块并按照他们的指南进行操作。

在此处输入图像描述

NOTICE : My application is broken into several pages/components, the page were I am implementing that interface (Trello) is called BoardPageComponent .注意:我的应用程序分为几个页面/组件,我正在实现该接口(Trello)的页面称为BoardPageComponent

First I added the cdkDrag directive and the element became draggable which is a good start!首先,我添加了cdkDrag指令,元素变得可拖动,这是一个好的开始!

Then I added the cdkDropList directive to the parent element, the children elements were still draggable BUT their style no longer works while they are dragged !然后我将cdkDropList指令添加到父元素中,子元素仍然可以拖动,但是它们的样式在被拖动时不再起作用!

Solution解决方案

When dragging an element inside of a cdkDropList the DragAndDropModule creates a clone of that element but at the body level of the document.当在cdkDropList中拖动元素时, DragAndDropModule会创建该元素的克隆,但位于文档的正文级别。 So if your component is encapsulated then it's style won't apply !因此,如果您的组件被封装,那么它的样式将不适用!

Solution 1: One quick solution would be to just move the style of that draggable element and put it in the global style file.解决方案 1:一种快速的解决方案是移动该可拖动元素的样式并将其放入全局样式文件中。

Solution 2: Another solution would be to disable the encapsulation of that component with ViewEncaplusation.None :解决方案 2:另一种解决方案是使用ViewEncaplusation.None禁用该组件的封装:

@Component({
  selector: 'app-board-page',
  templateUrl: './board-page.component.html',
  styleUrls: ['./board-page.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class BoardPageComponent implements OnInit, OnDestroy {
  ....
}

This will work but you should be aware that this may leak some style to other components of your application.这会起作用,但您应该知道这可能会将某些样式泄漏到应用程序的其他组件中。 So make sure to encapsulate the component's style manually.所以一定要手动封装组件的样式。

Or maybe there is another way??或者也许还有另一种方式?

In your scss file add specific css in host ng deep selector在您的 scss 文件中,在主机 ng 深度选择器中添加特定的 css

:host ::ng-deep h2 {
    color: red;
 }

I had the same issue: the dragged element was unstyled.我有同样的问题:拖动的元素没有样式。 And yes, there may be another way.是的,可能还有另一种方式。

While keeping the default ViewEncapsulation.Emulated , my solution was to ensure my component's CSS was not overly scoped (eg having draggable parent's selectors in the path for draggable may be too specific).在保持默认ViewEncapsulation.Emulated的同时,我的解决方案是确保我的组件的 CSS 没有过度限定范围(例如,在可拖动的路径中具有可拖动父级的选择器可能过于具体)。

Using .cdk-drag-preview was helpful to me.使用.cdk-drag-preview对我很有帮助。

My take on this answer我对这个答案的看法

TLDR: I had nested selectors in my SCSS code, and the styles were not used because the drag action creates a copy of the element, but without its parents (which I had in the nested selector) TLDR:我的 SCSS 代码中有嵌套选择器,并且没有使用 styles,因为拖动操作会创建元素的副本,但没有它的父元素(我在嵌套选择器中有)

Here is how I got my styles to be properly copied across.这是我如何正确复制 styles 的方法。

What is happening?怎么了?


When the .cdk-drag-preview is created, it copies the element that is being dragged.创建.cdk-drag-preview时,它会复制正在拖动的元素。

It is created and appended near the end of the <body> element of the HTML.它是在 HTML 的<body>元素末尾附近创建并附加的。

The most important thing here is that only the dragged element is copied, and not its parent elements.这里最重要的是只复制被拖动的元素,而不是它的父元素。

What is the problem?问题是什么?


In my case, the problem was that my SCSS selector was nested, and it expected my dragged element to start with a parent class, which doesn't exist when we drag.在我的情况下,问题是我的 SCSS 选择器是嵌套的,它期望我拖动的元素以父 class 开头,当我们拖动时它不存在。

Example:例子:

.example-parent-class {
  // Styles for the parent element

  .example-dragged-class { 
    // Styles for the item that we want to drag
  }
}

And when we drag, this is what was recorded in the <body> tag:而当我们拖拽的时候, <body>标签中记录的是这样的:

<body>
  <div cdkdrag class="example-dragged-class cdk-drag cdk-drag-preview"></div>
</body>

and the parent element nor it's class was nowhere to be found, thus my styles were not working.并且父元素及其 class 无处可寻,因此我的 styles 无法正常工作。

How to find this information?如何找到这些信息?


While dragging the element with the Inspector open (F12 on Chrome), you can quickly right-click, and go to the </body> selector in your Elements tab.在检查器打开的情况下拖动元素(Chrome 上的 F12),您可以快速右键单击,然后 go 到Elements选项卡中的</body>选择器。 The dragged element will still stay dragged and you can inspect the HTML that is being generated.拖动的元素仍将保持拖动状态,您可以检查正在生成的 HTML。

What is the solution?解决办法是什么?


My fix was to remove that nesting, and let my dragged element's class be standalone in my components scss so it can be accurately used by the .cdk-drag-preview我的解决方法是删除该嵌套,并让我拖动的元素的 class 在我的组件 scss 中独立,以便.cdk-drag-preview可以准确地使用它

Example:例子:

.example-parent-class {
  // Styles for the parent element
}

.example-dragged-class {
  // Styles for the item that we want to drag
}

And thus finally, the styles for my original element were properly copied across, there was no need for additional setup or anything similar.因此,最后,我的原始元素的 styles 被正确复制,不需要额外的设置或类似的东西。

Maybe additionally you can add styles for the placeholder or something similar.也许您还可以为占位符添加 styles 或类似的东西。

Example:例子:

.cdk-drag-placeholder {
  opacity: 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM