Open serjo96 opened 6 years ago
Hi @serjo96
the directive accepts either Array or FormArray. In your case you pass an observable [sortablejs]="todos$"
which is of course wrong: observables are not yet supported (might be a good idea in future actually).
@serjo96 Don't pass anything and it will stop attempts of slicing the things (e.g. <ul sortablejs>
) but you would be left with the implementation of onUpdate / onAdd / onRemove on your own.
@smnbbrv if i understand, i need add atribute sortablejs and [sortablejsOptions]='MyupdateMethod'?
yes, something similar to this, in particular [sortablejsOptions]='{ onUpdate: yourOnUpdate }' where onUpdate will be passed to the original library https://github.com/RubaXa/Sortable
Please note that onUpdate manages the updates of the current list only. If you drag / drop from / to different lists you need to use onAdd and onRemove additionally
@smnbbrv yea, thaat good, but how i now may take changed array?
@serjo96 you have an array that is rendered with ngFor
; just take this array in onUpdate event...
See https://smnbbrv.github.io/angular-sortablejs-demo/custom-options or its implementation https://github.com/smnbbrv/angular-sortablejs-demo/blob/master/src/app/examples/sortable-with-options/sortable-with-options.component.ts
yea. i see this exaples,
but the problem if i write like this[sortablejsOptions]='{onUpdate: test()}'
its mean i wanna call function all time and i take infinity loop, how i may call function and give him my array?
Or add array like this, but i take not changed array
eventOptions: SortablejsOptions = {
onUpdate: () => this.store.dispatch( updateList(this.state) );
};
Have any another way to take array?)
Please post a plunkr with what you tried. It's hard to say what you are doing wrong until I have a full picture
if add my array like argument, function be called infinity, so i do like this, and take all time old array https://stackblitz.com/edit/angular-jhdafj?file=app%2Fapp.component.html
So, i change tactic and return to old realisation with model bind, all work fine , but its strange. console.log(this.state) give me my new sorted array, but when i give this new array to my action and dispatch, in reducer i tike old array. Update stackblitz
<ul class="todo-list" [sortablejs]="state" [sortablejsOptions]='eventOptions'>
<li class="todo"
*ngFor="let todo of state let i = index;"
[ngClass]="{'todo--done': todo.done, 'todo--is-over': toDate(todo.date) < currentTime, 'todo--close-date': toDate(todo.date).getDate() - currentTime.getDate() <= 3 && todo.date > currentTime}"
>
//give me new sorted array
eventOptions: SortablejsOptions = {
onUpdate: () => console.log(this.state)
};
//give me my old array
eventOptions: SortablejsOptions = {
onUpdate: () => {
let arr = this.state;
console.log(arr)
this.store.dispatch(updateList(arr))
}
};
@serjo96 this is a correct approach I would say. It works fine I guess?
@smnbbrv Not really. html sort successfully passes without errors, but here the array comes old, in the example that I attached, it is evident that in the console after the call of the onupdate comes the old array, if i try use another function in on update.
https://stackblitz.com/edit/angular-jhdafj?file=app%2Fapp.component.html
ok, got it.
See https://stackblitz.com/edit/angular-1kl9cz?file=app/app.component.ts
This works somehow but I am not sure this is a really nice way to deal with the problem.
The problem itself is that after the array gets updated the changes are propagated to the store and of course they come back to the component. setTimeout
is forcing angular to rerender the things asynchronously, so, somehow it works.
Cannot promise anything better for now. I am thinking of v3 where this could be addressed as well.
please don't close it I renamed it for keeping in mind the main idea
i dont know what i do, but all works fine without setTiemout 😂 maybe it because i use splice, i remove all splice and all work!
@serjo96 shouldn't you pass todo$ | async
here:
<ul class="todo-list" [sortablejs]="todos$">
?
For anyone (like me) who found themselves here looking for an ngrx example working together with this lib, look no further!
example.component.ts
public items: Store<any[]> = this.store.select(selectItems);
public sortableOptions: SortablejsOptions = {
// ...options,
onStart: e => this.onDrag(e),
onUpdate: e => this.onDrop(e)
};
constructor(private store: Store<AppState>) {}
private onDrag(event: any) {
const { oldIndex, newIndex } = event;
return this.store.dispatch(
new DragStart({ oldIndex, newIndex })
);
}
private onDrop(event: any) {
const { oldIndex, newIndex } = event;
return this.store.dispatch(
new DragEnd({ oldIndex, newIndex })
);
}
example.component.html
<div [sortablejs]="items | async" [sortablejsOptions]="sortableOptions">
<div *ngFor="let item of items | async">
<child-component [item]="item"></child-component>
</div>
</div>
@rowanhogan Thanks a lot but you are not providing the actual actions and the reducers that will actually do the work in the store! Are you working with entity or not?
Hi there, my contribution to this issue. I have recently upgraded to Angular 9 and my old version of sortablejs did not work anymore so I upgraded. However this code worked fine in version 2.7.0 of angular-sortablejs.
<div class="list-group" [sortablejs]="todos | async">
<app-todo *ngFor="let element of todos | async; index as i"
[todo]=todo
[index]=i>
</app-todo>
</div>
With the update to ngx-sortablejs 3.1.4 it does not work correctly anymore. Drag and drop does work but there seems to be another update after you drop the item causing a weird 'jump' in the element you dropped. Also, it sometimes keeps the items in the correct order and sometimes it just shuffles. After some digging in the library it seems that the target array gets out of sync with the observable at some point.
It is mysterious to me why it worked perfectly fine in the old version.
Hello!
I use ngrx to save my array, and read from it, But how i understand, sortablejs + ngrx its nor good idea. If i wanna change array in ngrx i first need dispatch action, but sortablejs try splice this arrays and i take erorr this.target.splice is not a function
component
template