Драгула выясняет порядок сортировки - как отключить
Я использую Dragula для функциональности Drag and Drop. Это работает, пока я не обновлю свой список со стороны сервера:
this.columnList = newValue;
Это говорит о том, что Dragula хочет сохранить порядок в списке, как это было раньше, поэтому он портит порядок сортировки на стороне сервера. Мне не нужен этот функционал. Я прочитал документацию, учебные пособия, примеры, но не могу найти, как отключить автосортировку в Dragula.
1 ответ
Я совершенно уверен, что нет автоматической сортировки, по крайней мере, по умолчанию. Минимальные автономные примеры - наш друг. Ну, независимо от того, что в Интернете можно использовать больше примеров, и, хотя трудно доказать отрицательность, я покажу, что в случае по умолчанию отсутствует автоматическая сортировка, и попытаюсь угадать, в чем проблема.
Извините, только после того, как я понял, что вы используете чистый JS и, вероятно, используете AngularJS, а не Angular2. Несмотря на это, следующее все равно должно быть несколько полезным.
Сначала нам нужна простая база кода, давайте используем Angular-CLI для ее создания ( https://www.npmjs.com/package/angular-cli): затем следуйте инструкциям Как настроить angular-quickstart с помощью ng2-dragula и мы будет иметь точно такую же стартовую базу.
Теперь замените содержимое app.component.html на:
<div><button (click)="inOrderGreekAlphabet()">In Order Greek Alphabet</button></div>
<div><button (click)="reversedGreekAlphabet()">Reversed Greek Alphabet</button></div>
<div><button (click)="displyStateOfItems()">Display state of Items</button></div>
<div>
<div class='wrapper'>
<div class='container' [dragula]='"first-bag"' [dragulaModel]="items">
<div *ngFor="let item of items">{{item}}</div>
</div>
</div>
</div>
Заменить содержимое app.component.ts следующим образом:
import {Component} from '@angular/core';
import {DragulaService} from 'ng2-dragula/ng2-dragula';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
viewProviders: [DragulaService]
})
export class AppComponent {
public items: string[];
private GREEK_ALPHABET:string[] = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega"];
constructor() {
this.inOrderGreekAlphabet();
}
public inOrderGreekAlphabet(){
this.items = this.GREEK_ALPHABET.slice();
}
public reversedGreekAlphabet() {
this.items = this.GREEK_ALPHABET.reverse();
}
public displyStateOfItems(){
alert(JSON.stringify(this.items));
}
}
Если вы запустите вышеописанное, вы обнаружите, что модель синхронизируется со списком, как это ясно показано с помощью кнопки " Показать состояние элементов". Однако если мы удалим [dragulaModel]="items"
из app.component.html мы обнаружим, что модель не синхронизирована. Дело не в том, что драгула делает что-то дополнительное, на самом деле оно делает что-то меньшее.
Теперь, чтобы исправить проблему...
При синхронизации локального состояния мы можем попробовать это несколькими способами:
Сначала обратите внимание, что при добавлении [dragulaModel]="items"
синхронизирует список с массивом, но нам все еще нужна ловушка для нашего пользовательского кода синхронизации сервера, подробнее об этом позже.
Если мы игнорируем каркас Dragula и, возможно, попытаемся создать метод установки для получения элементов. Однако, если мы переименуем все экземпляры элементов в _items, а затем добавим:
//This is to demonstrate an issue, this is NOT A Solution!
get items():string[]{
console.log("call from getter: could do server sync here?");
return this._items;
}
set items(i:string[]){
console.log("call from setter: or perhaps here?");
this._items = i;
}
Однако вышеприведенное НЕ БУДЕТ РАБОТАТЬ, или, скорее, это может сработать, но просмотр журналов консоли показывает, что установщик вызывается один раз, а затем весь последующий доступ выполняется с помощью получателя, и что получатель вызывается много раз во время перетаскивания, если пользователь зависает и перемещается, возможно, сотни звонков могут быть сгенерированы в течение нескольких секунд. Кроме того, было бы неплохо сообщить пользователю, нужно ли сохранять страницу или нет, делая сравнение массива в потенциально неограниченном списке, неопределенное количество раз просто не звучит как хорошая идея, и хотя может быть Чистые решения Java/TypeScript, которые могут решить эту проблему, предоставляют способ выполнить проверку только один раз, когда элемент отброшен.
Добавьте следующий код, заменив конструктор, и удалите этот метод установки / получения, потому что это была глупая идея (мы действительно просто заинтересованы в отбрасывании, но полнота никогда не повредит):
constructor(private dragulaService: DragulaService) {
dragulaService.drag.subscribe((value) => {
console.log(`drag: ${value[0]}`);
this.onDrag(value.slice(1));
});
dragulaService.drop.subscribe((value) => {
console.log(`drop: ${value[0]}`);
this.onDrop(value.slice(1));
});
dragulaService.over.subscribe((value) => {
console.log(`over: ${value[0]}`);
this.onOver(value.slice(1));
});
dragulaService.out.subscribe((value) => {
console.log(`out: ${value[0]}`);
this.onOut(value.slice(1));
});
this.inOrderGreekAlphabet();
}
private onDrag(args) {
let [e, el] = args;
//do something
}
private onDrop(args) {
let [e, el] = args;
// do something
}
private onOver(args) {
let [e, el, container] = args;
// do something
}
private onOut(args) {
let [e, el, container] = args;
// do something
}
Вышеуказанное было взято с https://github.com/valor-software/ng2-dragula и предоставляет возможность вручную выполнить синхронизацию без использования dragulaModel
директива, но мы также можем опираться на эту директиву, как показано в следующем разделе документации ( https://github.com/valor-software/ng2-dragula), поэтому вместо выполнения выше, минимально нам просто нужно (и мы должны использовать директиву dragulaModel в этом случае):
constructor(private dragulaService: DragulaService) {
dragulaService.dropModel.subscribe((value) => {
console.log(`dropModel: ${value[0]}`);
this.onDropModel(value);
});
this.inOrderGreekAlphabet();
}
private onDropModel(args){
let [bagName, el, target, source] = args;
//do something, such as sync items with the server.
//or setting a flag to indicate if items is different from when it was last saved
}
И у вас должно быть хорошее рабочее решение.