0

我们在 Angular 8 中构建了不同的模板,其中包含滑块、产品列表和一些带有图像、文本等的块。我需要创建一个拖放页面构建器,用户可以在其中选择模板、添加或删除任何元素和编辑元素(样式)例如带有图像、标题、价格、按钮等的产品框。我不知道如何继续使用技术堆栈,最终将模板保存为 Angular。大多数组件都显示从 API 加载的动态数据

  • 画布是没有选择
  • 我需要为页面上组件/元素的位置创建一个 json 对象吗?
  • 使用“ComponentFactoryResolver”动态创建组件有帮助吗?但是如何在实时编辑时绑定数据以及在使用角度构建时保存后
  • 在可放置区域中创建组件时,我将如何检测它是否包含图像或文本,并且我必须针对所选元素打开可编辑选项

任何帮助将不胜感激,我愿意接受任何讨论

4

1 回答 1

2

从您的描述看来,您正在尝试构建仪表板系统或 HTML WYSIWYG 编辑器。这是一个相当广泛的架构问题,方法将很大程度上取决于您的项目的要求/时间框架等...我的第一个建议是进行搜索,看看是否有任何工具已经可以满足您的需求。即具有自定义功能的 Ck 编辑器是否满足您的需求?...

找不到一个,如果你需要自己动手,这里有一些从我的经验中吸取的教训。

  • 要么创建一个使用本机 HTML 拖放的自定义指令,要么使用其中一个为您提供拖放的角度库(即材料拖放等...)
  • 定义您的页面模型的外观。
  • 利用 Observables 确保各个组件之间保持隔离。还可以使用共享服务/可观察对象在彼此之间进行通信
  • 将尽可能多的常见“属性”组合在一起,并使它们成为您的基类的一部分。

定义您的页面模型的外观

  • 您将如何存储用户所做操作的表示?在 HTML、JSON 中?
  • 我们在内部就使用 HTML 而不是 JSON 进行了辩论,但最终我们选择了 JSON,因为团队认为它更适合他们。但您也可以使用 HTML 作为模型。例如:

export interface Widget {
  name: string;
  type: string;
  style: CSSProperties;
  widgets?: Widget[];
}

export interface Text extends Widget {
  textContent: string;
}

export interface Image extends Widget {
  url: string;
}

export interface Table extends Widget {
  source: string;
}

您总是可以扩充您的界面,但至少要花足够的时间了解结构的外观。如果完成属性,添加具有自己接口的新组件变得轻而易举。在某些方面,这是使用 HTML 作为模型可能更有意义的地方。

但是有了这个模型,您的“TextComponent”可以期望向它提供符合“Text”接口的数据。图像,表格等相同...

有了这个,您可以使用您希望使用的特定属性标记组件的 html。即在TextComponent 的情况下,您只需"{{textContent}}在HTML 中使用它,因为它是该组件接口的属性。

拖放

  • 了解是否需要支持嵌套拖拽?
  • 根据您项目的要求,找到一个具有您可以使用的拖放功能的库(材料拖放等......)
  • 或者创建一个指令来实现 HTML 5 的原生拖放功能

无论您采用哪种方法,所有拖放都有一个“放置”事件。当用户停止拖动时触发此事件。大多数拖放工具还允许您在“拖动”期间传递数据,即使“拖放”事件处理程序可以处理它。

定义模型后,您可以在拖动事件中传递当前组件的模型。在“Drop”上,您可以检查widget.type传递的数据。这将允许您确定您正在处理的组件类型。

利用 Observables 确保各个组件保持相互隔离

  • 一开始,当您只有少数几个组件时,让您的各种组件直接相互交互是很诱人的。甚至可能修改彼此的状态和/或数据。
  • 但是,随着组件列表的增长,并且您开始需要组件交互,您将很快开始发现问题。即在组件A中选择日期范围还需要更新组件B中显示的数据

我们最终采用了状态管理解决方案 (NgRX),以帮助将状态与布局分开。由于我们是在中途进行的,所以一开始很痛苦,但是一旦完成,添加新组件就会变得更快。仅供参考:您不需要使用 NgRx,一个服务或共享的 observable 将跟踪您的各种组件的数据也可以。例如,使用 RxJS BehaviorSubject 允许延迟订阅者获取当前值

组件到 DataStore 示例

这允许处理诸如

  • 组件 B 依赖于组件 A
  • 当组件 A 发生更改,而不是组件 A 循环遍历所有组件以查找依赖项时,组件 B 订阅存储并更改自己的一个属性 Component A Changes
  • 这使我们能够将布局逻辑与应用程序中的业务逻辑分开。即,每当A公司更新商店时,如果有要应用的业务逻辑,则在显示组件之外进行处理。随着我们的组件列表不断增加,这有所帮助。
  • 这使我们能够处理多组件事件。即,如果用户按住 shift 并选择多个组件,并且想要更改所有选定组件的背景颜色。背景颜色的选定组件 css 属性在商店 (NgRX) 中更新,并且组件(通过订阅和更改检测)自动在屏幕上更新。

最终,这种方法使我们能够将组件的表示逻辑与数据逻辑分离。

这可能会变得非常复杂,具体取决于您需要的复杂程度。如果这是一个项目,您只需要快速而肮脏地完成某些事情,那么当然要做您必须做的事情。但是,如果您有时间专注于此,我建议您花一些时间来了解您的模型以及组件交互将是什么。

我希望其中的一些内容会有所帮助。祝你好运。

于 2020-02-17T17:26:44.190 回答