File

src/app/layout/html-builder/page-editor/page-editor.component.ts

Implements

OnInit

Metadata

selector app-page-editor
styleUrls ./page-editor.component.less
templateUrl ./page-editor.component.html

Index

Properties
Methods

Constructor

constructor(settingService: HtmlBuilderSettingService, pageEditorService: PageEditorService)
Parameters :
Name Type Optional
settingService HtmlBuilderSettingService No
pageEditorService PageEditorService No

Methods

Public change
change(value: any)
Parameters :
Name Type Optional
value any No
Returns : void
Public drop
drop(event: CdkDragDrop)
Parameters :
Name Type Optional
event CdkDragDrop<DropItem> No
Returns : void
Public ngOnInit
ngOnInit()
Returns : void
Public onSave
onSave()
Returns : void
Public saveCancel
saveCancel()
Returns : void
Public savePage
savePage()
Returns : void

Properties

Public heroes
Default value : new Array(20).fill(100)
Public isSaveLoading
Default value : false
Public isSaveVisible
Default value : false
Public pageEditorService
Type : PageEditorService
players
Type : ElementRef<HTMLElement>[]
Decorators :
@ViewChildren('player', {read: ElementRef})
Public settingService
Type : HtmlBuilderSettingService
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component, ElementRef, OnInit, ViewChildren } from '@angular/core';
import { HtmlBuilderSettingService } from '../html-builder-setting.service';
import { DropItem, PageEditorService } from './page-editor.service';

@Component({
  selector: 'app-page-editor',
  templateUrl: './page-editor.component.html',
  styleUrls: ['./page-editor.component.less'],
})
export class PageEditorComponent implements OnInit {

  // 测试数据
  public heroes = new Array(20).fill(100);
  // 显示页面保存表单
  public isSaveVisible = false;
  // 页面保存中
  public isSaveLoading = false;
  // 渲染组件
  @ViewChildren('player', { read: ElementRef })
  players: ElementRef<HTMLElement>[];

  constructor(
    public settingService: HtmlBuilderSettingService,
    public pageEditorService: PageEditorService,
  ) { }

  // 拖放组件
  public drop(event: CdkDragDrop<DropItem>) {
    // console.log('In PageEditorComponent');
    // console.log(`previousIndex => ${event.previousIndex}, currentIndex => ${event.currentIndex}`);
    // console.log('previousContainer.data => ', event.previousContainer.data);
    const dragData: DropItem = event.previousContainer.data;
    if (event.previousContainer === event.container) {
      moveItemInArray(this.pageEditorService.dropItems, event.previousIndex, event.currentIndex);
    } else {
      // console.log(event.container.element.nativeElement);
      this.pageEditorService.insertDropItem(new DropItem(dragData.code), event.currentIndex);
    }
  }

  // 弹出页面保存表单
  public onSave() {
    // this.players.forEach(player => {
    //  console.log(player.nativeElement.innerHTML);
    // });
    console.log(this.pageEditorService.dropItems);
    this.isSaveVisible = true;
  }

  // 保存页面
  public savePage(): void {
    this.isSaveLoading = true;
    setTimeout(() => {
      this.isSaveVisible = false;
      this.isSaveLoading = false;
    }, 2000);
  }

  // 取消页面保存
  public saveCancel(): void {
    this.isSaveVisible = false;
  }

  // 属性表更改时
  public change(value: any) {
    // console.log(value);
    // console.log(this.pageEditorService.editItem.code);
    if (this.pageEditorService.editItem.code === 'app-ch-grid') {
      // if (value.layout.length) {
      const colItemsTemp = this.pageEditorService.updateDropConnect(value.layout);
      // 初始化ch-grid栅格数据
      if (this.pageEditorService.editItem.colItems.length) {
        colItemsTemp.forEach((_, index: number) => {
          if (this.pageEditorService.editItem.colItems[index]) {
            colItemsTemp[index].dropItems = this.pageEditorService.editItem.colItems[index].dropItems;
          }
        });
      }
      this.pageEditorService.editItem.data = Object.assign({}, this.pageEditorService.editItem.data, value);
      this.pageEditorService.editItem.colItems = colItemsTemp;
      // }
    } else {
      this.pageEditorService.editItem.data = Object.assign({}, this.pageEditorService.editItem.data, value);
    }
  }

  public ngOnInit(): void { }

}
<nz-sider nzWidth="200px" nzTheme="light">
  <ul nz-menu nzMode="inline" class="sider-menu">
    <li nz-submenu nzTitle="布局" nzIcon="appstore">
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-grid'}">
        <li class="drag-unit" nz-menu-item cdkDrag>栅格</li>
      </ul>
    </li>
    <li nz-submenu nzTitle="文本" nzIcon="font-size" nzOpen>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-head'}">
        <li class="drag-unit" nz-menu-item cdkDrag>标题</li>
      </ul>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-p'}">
        <li class="drag-unit" nz-menu-item cdkDrag>段落</li>
      </ul>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-list'}">
        <li class="drag-unit" nz-menu-item cdkDrag>列表</li>
      </ul>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-link'}">
        <li class="drag-unit" nz-menu-item cdkDrag>链接/按钮</li>
      </ul>
    </li>
    <li nz-submenu nzTitle="图片" nzIcon="picture">
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-img'}">
        <li class="drag-unit" nz-menu-item cdkDrag>单图片/视频</li>
      </ul>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-carousel'}">
        <li class="drag-unit" nz-menu-item cdkDrag>轮播图</li>
      </ul>
    </li>
    <li nz-submenu nzTitle="卡片" nzIcon="credit-card">
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-info-card'}">
        <li class="drag-unit" nz-menu-item cdkDrag>信息卡片</li>
      </ul>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-tour-card'}">
        <li class="drag-unit" nz-menu-item cdkDrag>线路卡片</li>
      </ul>
    </li>
    <li nz-submenu nzTitle="表单" nzIcon="form">
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-tailormade-form'}">
        <li class="drag-unit" nz-menu-item cdkDrag>Tailormade</li>
      </ul>
      <ul class="drag-wrap" cdkDropList [cdkDropListConnectedTo]="pageEditorService.dropConnectPlayground"
        [cdkDropListData]="{code:'app-ch-tour-form'}">
        <li class="drag-unit" nz-menu-item cdkDrag>精华线路</li>
      </ul>
    </li>
  </ul>
</nz-sider>
<nz-layout class="inner-layout">
  <div class="tools-button">
    <button nz-button nzType="default" (click)="onSave()">保存页面</button>
    <nz-radio-group [(ngModel)]="settingService.previewMode" class="right">
      <label nz-radio-button nzValue="pc">电脑</label>
      <label nz-radio-button nzValue="iPhoneSmall">iPhone XS</label>
      <label nz-radio-button nzValue="iPhoneLarge">iPhone XS Max</label>
    </nz-radio-group>
  </div>
  <nz-content>
    <div class="inner-content fix-phone"
      [ngClass]="{'fix-phone': settingService.previewMode !== 'pc','w375': settingService.previewMode === 'iPhoneSmall','w414': settingService.previewMode === 'iPhoneLarge'}">
      <div class="playground container" id="playground" cdkDropList (cdkDropListDropped)="drop($event)">
        <div class="playground-item" *ngFor="let item of pageEditorService.dropItems; index as i;" cdkDrag>
          <app-ch-grid #player [gridItem]="item" [itemIndex]="i" [itemParent]="pageEditorService.dropItems"
            *ngIf="item.code === 'app-ch-grid'">
          </app-ch-grid>
          <app-ch-head #player [item]="item" [itemIndex]="i" [itemParent]="pageEditorService.dropItems"
            *ngIf="item.code === 'app-ch-head'">
          </app-ch-head>
          <app-ch-p #player [item]="item" *ngIf="item.code === 'app-ch-p'">
          </app-ch-p>
          <app-ch-list #player [item]="item" *ngIf="item.code === 'app-ch-list'">
          </app-ch-list>
          <app-ch-link #player [item]="item" *ngIf="item.code === 'app-ch-link'">
          </app-ch-link>
          <app-ch-img #player [item]="item" *ngIf="item.code === 'app-ch-img'">
          </app-ch-img>
          <app-ch-carousel #player [item]="item" *ngIf="item.code === 'app-ch-carousel'">
          </app-ch-carousel>
          <app-ch-info-card #player [item]="item" *ngIf="item.code === 'app-ch-info-card'">
          </app-ch-info-card>
          <app-ch-tour-card #player [item]="item" *ngIf="item.code === 'app-ch-tour-card'">
          </app-ch-tour-card>
          <app-ch-tailormade-form #player [item]="item" *ngIf="item.code === 'app-ch-tailormade-form'">
          </app-ch-tailormade-form>
          <app-ch-tour-form #player [item]="item" *ngIf="item.code === 'app-ch-tour-form'">
          </app-ch-tour-form>
          <div class="preview-holder" *cdkDragPreview>一个无情的占位符.</div>
          <div class="custom-placeholder" *cdkDragPlaceholder></div>
        </div>
      </div>
    </div>
  </nz-content>
  <div class="prop-content">
    <div class="prop-forms card-container" [ngClass]="{'op0': !pageEditorService.schema}">
      <nz-tabset nzType="card">
        <nz-tab nzTitle="属性">
          <sf *ngIf="pageEditorService.schema" [schema]="pageEditorService.schema"
            [formData]="pageEditorService.defaultEditItemValue" (formChange)="change($event)" layout="vertical"
            button="none">
          </sf>
        </nz-tab>
        <nz-tab nzTitle="通用">
          <sf [schema]="pageEditorService.commonSchema" [formData]="pageEditorService.defaultEditItemValue"
            (formChange)="change($event)" layout="vertical" button="none">
          </sf>
        </nz-tab>
      </nz-tabset>
    </div>
  </div>
</nz-layout>

./page-editor.component.less

nz-sider {
  overflow: auto;
  height: 100%;
  position: fixed;
  left: 0;
}

.sider-menu {
  height: 100%;
  border-right: 0;
}

.inner-layout {
  padding: 0 24px 24px;
  margin-left: 200px;
}

nz-breadcrumb {
  margin: 16px 0;
}

nz-content {
  background-color: transparent;
}

.inner-content {
  background: #fff;
  min-height: 1024px;
  max-width: 1170px;
}

.prop-content {
  height: 100%;
  width: 100%;
  position: fixed;
  top: 113px;
  left: 1416px;
  z-index: 100;

  .prop-forms {
    width: 468px;
    margin-top: 24px;
    transition: opacity 250ms cubic-bezier(0, 0, 0.2, 1);
    opacity: 1;

    .save-button {
      margin-top: 8px;
    }
  }

  .op0 {
    opacity: 0;
  }
}

:host ::ng-deep .ant-form-item {
  margin: 0 0 8px;
}

:host ::ng-deep .sf__array-add {
  margin-top: 12px;
}

/* 工具栏 */
.tools-button {
  padding: 8px 24px;
  position: sticky;
  top: 64px;
  background-color: #fff;
  box-shadow: 0px 1px 0 #eee;
  margin: 0 -24px 24px;
  border-left: 1px solid #f1f1f1;
  z-index: 100;
}

[nz-button] {
  margin-right: 8px;
}

/*属性框样式*/
.card-container ::ng-deep .ant-tabs-card .ant-tabs-content {
  margin-top: -17px;
}

.card-container ::ng-deep .ant-tabs-card .ant-tabs-content .ant-tabs-tabpane {
  background: #fff;
  padding: 16px;
}

.card-container ::ng-deep .ant-tabs-card .ant-tabs-content .ant-tabs-tabpane-active {
  max-height: 740px;
  overflow-y: scroll;
}

.card-container ::ng-deep .ant-tabs-card .ant-tabs-bar {
  border-color: #fff;
}

.card-container ::ng-deep .ant-tabs-card .ant-tabs-bar .ant-tabs-tab {
  border-color: transparent;
  background: transparent;
}

.card-container ::ng-deep .ant-tabs-card .ant-tabs-bar .ant-tabs-tab-active {
  border-color: #fff;
  background: #fff;
  border-radius: 0;
}

/* 拖放特效 */
.playground {
  min-height: 1024px;
  padding-top: 1rem;
  padding-bottom: 1rem;
  overflow: hidden;
}

.drag-unit {
  background: #fff;
  margin: 0;
  line-height: 40px;
}

.drag-wrap {
  height: 40px;
  background: #f1f1f1;
}

.cdk-drag-preview {
  box-sizing: border-box;
  border-radius: 4px;
  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
    0 8px 10px 1px rgba(0, 0, 0, 0.14),
    0 3px 14px 2px rgba(0, 0, 0, 0.12);
}

.cdk-drag-placeholder {
  background: #ccc;
  border: dotted 3px #999;
  height: 48px;
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  opacity: 1;
}

.cdk-drag-animating {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

.playground.cdk-drop-list-dragging .playground-item:not(.cdk-drag-placeholder) {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

/*
.playground.cdk-drop-list-dragging {
  background-color:#e6f7ff;
}
*/
.preview-holder.cdk-drag-preview {
  height: 48px;
  line-height: 48px;
  padding: 0 12px;
  border: 1px solid #333;
  background: #fff;
}

.custom-placeholder {
  background: #ccc;
  border: dotted 3px #999;
  height: 48px;
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  opacity: 1;
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""