【问题标题】:What technology stack to choose for drag and drop page builder为拖放页面构建器选择什么技术堆栈
【发布时间】:2020-06-01 13:15:15
【问题描述】:

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

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

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

【问题讨论】:

    标签: node.js angular drag-and-drop builder angular-material-8


    【解决方案1】:

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

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

    • 要么创建一个使用原生 HTML 拖放的自定义指令,要么使用提供拖放功能的 Angular 库之一(即材料拖放等...)
    • 定义您的页面模型的外观。
    • 利用 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,您只需在 HTML 中使用 "{{textContent}},因为它是该组件接口的属性。

    拖放

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

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

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

    利用 Observables 确保各个组件之间保持隔离

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

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

    这允许处理诸如

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

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

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

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

    【讨论】:

    • 非常感谢您的详细解释,我会选择 JSON 来展示布局,选择有角度的材质来拖放,而界面声音则适合 CSS 属性编辑。让我做 POC,如果需要我会联系。再次感谢。
    猜你喜欢
    • 2015-10-12
    • 2020-03-13
    • 1970-01-01
    • 2016-10-06
    • 2016-05-04
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多