Angular 6: HTML-таблица создает динамические столбцы и строки - PullRequest
0 голосов
/ 12 июня 2019

Здесь используется Angular 6

Я хотел, чтобы некоторые материалы касались разработки одного из моих компонентов пользовательского интерфейса. Таким образом, в основном текущий функционально мы уже разработали в AngularJs, но в этом новое приложение, использующее Angular 6, я хотел бы знать, есть ли лучшие способы сделать это.

Ниже приведен поток пользовательского интерфейса, который я хочу разработать.

Пользователь заполняет форму вверху, в основном текстовые поля и выпадающие списки.

После вышеупомянутого выбора я показываю таблицу HTML, имеющую 3 статических столбца и несколько кнопок для примера, как показано ниже:

ID Тип Env + Добавить столбец Удалить строку + Добавить строку

Выше Id, Type и Env - 3 статических столбца, которые всегда есть. Теперь, если пользователь хочет добавить столбец (динамический), он может нажать кнопку «Добавить столбец», где пользователь может ввести свое собственное имя в столбец. Также должно быть функционально удаление динамических столбцов. Как только пользователь завершит добавление столбцов, он может нажать на кнопку «Добавить строку», которая создаст динамическую строку, после чего пользователь сможет ввести данные в таблицу. Когда пользователь добавляет строку, он может нажать кнопку «Удалить строку», чтобы удалить эту строку.

После того, как пользователь завершит добавление столбцов и строк в таблицу, в конце появится кнопка отправки, которая отправит вышеприведенное в формате Json моему API, что затем сохраните всю форму.

К вашему сведению, у меня уже есть рабочие версии этого в angularjs, где я использую contenteditable для каждой строки, как показано ниже:

<tr ng-repeat="r in targetTable.rows">
 <td class="unique-id">{{r.id}}</td>
 <td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-blur="!r.id? addNewRow(r[column.id], r): undefined"></td>
 <td class="blank" colspan="2"></td>
</tr>

Смотрите демонстрацию здесь:

https://codepen.io/anon/pen/QXwjwM

Мне нужны входные данные для того, чтобы спроектировать эту HTML-таблицу со всеми функциональными возможностями добавления / удаления динамических строк и столбцов в Angular 6. Есть ли доступный открытый исходный код или кто-нибудь может помочь мне с некоторыми примерами. Или, если мне нужно создать все это вручную. так же, как я делал в AngularJs.

Спасибо

Кто-нибудь с входами?

Ответы [ 2 ]

2 голосов
/ 19 июня 2019

Объединив два комментария, я создал этот stackblitz

Я использовал таблицу материалов, потому что мне лень форматировать таблицу.Как уже отмечалось, единственное, что нам нужно для использования таблицы матов, это поставить в качестве источника данных элементы управления массива форм

dataSource = this.myformArray.controls;

Столбцы таблицы становятся похожими на

<ng-container matColumnDef="surname">
    <th mat-header-cell *matHeaderCellDef> Surname </th>
        <td mat-cell *matCellDef="let element">
       <input arrow-div [formControl]="element.get('surname')">
       </td>
  </ng-container>

Да, просто используя [formControl] = element.get ('nameOfField')

Забавная работа - сделать так, чтобы клавиши со стрелками работали для перемещения между "ячейками".Я использую директиву.Но поскольку я ненавижу создавать директиву с @Output(), я использую вспомогательный сервис.

Если мы не используем сервис, наш .html выглядит как

<input arrow-div [formControl]="element.get('id')" (arrowEvent)="move($event)">
<input arrow-div [formControl]="element.get('name')" (arrowEvent)="move($event)">
<input arrow-div [formControl]="element.get('surname')" (arrowEvent)="move($event)">
  ...

Если мы используем сервис, наш html становится более прозрачным

<input arrow-div [formControl]="element.get('id')" >
<input arrow-div [formControl]="element.get('name')" >
<input arrow-div [formControl]="element.get('surname')" >
...

И в приложениимы подписываемся на службу.

Служба проста

export class KeyBoardService {
  keyBoard:Subject<any>=new Subject<any>();
  sendMessage(message:any)
  {
    this.keyBoard.next(message)
  }
}

, просто предмет и метод для отправки значения субъекту.

Директива слушает только еслиКлавиша со стрелкой вниз и отправить ключ отправителю.Ну, я отправляю объект типа {element: ..., acction: ..} для отправки дополнительной информации.

export class ArrowDivDirective {
  constructor( private keyboardService:KeyBoardService,public element:ElementRef){}

  //@Output() arrowEvent:EventEmitter<any>=new EventEmitter();


  @HostListener('keydown', ['$event']) onKeyUp(e) {
    switch (e.keyCode)
    {
      case 38:
        this.keyboardService.sendMessage({element:this.element,action:'UP'})
        break;
      case 37:
        if (this.element.nativeElement.selectionStart<=0)
        {
        this.keyboardService.sendMessage({element:this.element,action:'LEFT'})
        e.preventDefault();
        }
        break;
      case 40:
        this.keyboardService.sendMessage({element:this.element,action:'DOWN'})
        break;
      case 39:
        if (this.element.nativeElement.selectionStart>=this.element.nativeElement.value.length)
        {
        this.keyboardService.sendMessage({element:this.element,action:'RIGTH'})
        e.preventDefault();
        }
        break;
    }
  }
}

Ну, я принимаю во внимание, когда вы в первый раз или в начале ввода отправляете или нет клавишу, когда мы нажимаем lfet и стрелку вправо.

app.componentнужно только подписаться на сервис и использовать ViewChildren для хранения всех входных данных.Будь осторожен!порядок просмотра детей в матричной таблице изменяется сверху вниз и слева направо

@ViewChildren(ArrowDivDirective) inputs:QueryList<ArrowDivDirective>

  constructor(private keyboardService:KeyBoardService){}
  ngOnInit()
  {
    this.keyboardService.keyBoard.subscribe(res=>{
      this.move(res)
    })
  }
  move(object)
  {
    const inputToArray=this.inputs.toArray()
    const rows=this.dataSource.length
    const cols=this.displayedColumns.length
    let index=inputToArray.findIndex(x=>x.element===object.element)
    switch (object.action)
    {
      case "UP":
        index--;
        break;
      case "DOWN":
        index++;
        break;
      case "LEFT":
        if (index-rows>=0)
          index-=rows;
        else
        {
          let rowActual=index%rows;
          if (rowActual>0)
            index=(rowActual-1)+(cols-1)*rows;
        }
        break;
      case "RIGTH":
      console.log(index+rows,inputToArray.length)
        if (index+rows<inputToArray.length)
          index+=rows;
        else
        {
          let rowActual=index%rows;
          if (rowActual<rows-1)
            index=(rowActual+1);

        }
        break;
    }
    if (index>=0 && index<this.inputs.length)
    {
      inputToArray[index].element.nativeElement.focus();
    }
  }

* ОБНОВЛЕНИЕ Если мы хотим добавить динамически столбцы, добавьте две новые переменные (плюсthe "displayColumns"

displayedColumns: string[] = ['name','surname','delete'];
displayedHead:string[]=['Name','Surname']
displayedFields:string[] = ['name','surname'];

И наша таблица становится такой:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <!-- All columns -->
   <ng-container *ngFor="let col of displayedFields;let i=index" [matColumnDef]="col">
      <th mat-header-cell *matHeaderCellDef> {{displayedHead[i]}} </th>
      <td mat-cell *matCellDef="let element">
        <input arrow-div [formControl]="element.get(col)">
      </td>
    </ng-container>
    <!---column delete-->
  <ng-container matColumnDef="delete">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let element;let i=index;">
        <button arrow-div mat-button (click)="delete(i)">delete</button>
    </td>
  </ng-container>


  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

Новая функция для добавления столбца должна добавить FormControl к каждой FormGroup массива, актуализировать переменные displayColumns,displayHead и displayFields

addColumn()
  {
    let newField="Column"+(this.displayedFields.length+1)

    this.myformArray.controls.forEach((group:FormGroup)=>{
      group.addControl(newField,new FormControl())
    })
    this.displayedHead.push(newField)
    this.dataSource = [...this.myformArray.controls];
    this.displayedFields.push(newField);
    this.displayedColumns=[...this.displayedFields,"delete"];
  }

В этом еще один стек Я добавляю эту функцию (также как удалить строку и как создать новую строку)

0 голосов
/ 12 июня 2019

Существует ui-grid сторонняя библиотека, которая предоставляет множество функций. Можете сослаться по ссылке

Если вы можете обновить, как указано здесь демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...