Skip to content

Commit 4049d61

Browse files
committed
wip(card-list): make getList() optional, allow setting children manually
vastly simplifies the 'simple' example. now it's actually simple.
1 parent 7b4f5cf commit 4049d61

File tree

6 files changed

+52
-43
lines changed

6 files changed

+52
-43
lines changed

packages/angular-skyhook-card-list/src/card-list.component.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
Component,
33
Input,
44
TemplateRef,
5+
ChangeDetectorRef,
56
ChangeDetectionStrategy,
67
ContentChildren,
78
QueryList,
@@ -25,7 +26,7 @@ import { CardListDirective } from './card-list.directive';
2526
selector: "skyhook-card-list",
2627
changeDetection: ChangeDetectionStrategy.OnPush,
2728
template: `
28-
<ng-container *ngFor="let card of children$ | async;
29+
<ng-container *ngFor="let card of children;
2930
let i = index;
3031
trackBy: trackById" >
3132
<ng-container *ngTemplateOutlet="template;
@@ -64,8 +65,9 @@ export class CardListComponent<Data>
6465
constructor(
6566
dnd: SkyhookDndService,
6667
el: ElementRef<HTMLElement>,
68+
cdr: ChangeDetectorRef,
6769
) {
68-
super(dnd, el);
70+
super(dnd, el, cdr);
6971
}
7072

7173
/** @ignore */

packages/angular-skyhook-card-list/src/card-list.directive.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
AfterViewInit,
88
ElementRef,
99
SimpleChanges,
10+
ChangeDetectorRef,
1011
} from '@angular/core';
1112
// @ts-ignore
1213
import { Subscription, Observable, BehaviorSubject } from "rxjs";
@@ -39,8 +40,7 @@ export class CardListDirective<Data> implements OnInit, OnChanges, OnDestroy, Af
3940
}
4041
}
4142

42-
/** @ignore */
43-
private children?: Iterable<Data>;
43+
@Input('cardListChildren') children?: Iterable<Data>;
4444
/** @ignore */
4545
private childrenSubject$ = new BehaviorSubject<Iterable<Data>>([]);
4646
/**
@@ -86,27 +86,31 @@ export class CardListDirective<Data> implements OnInit, OnChanges, OnDestroy, Af
8686
constructor(
8787
protected dnd: SkyhookDndService,
8888
protected el: ElementRef<HTMLElement>,
89+
protected cdr: ChangeDetectorRef,
8990
) {
9091
}
9192

9293
private updateSubscription() {
93-
const anyListId = (typeof this.listId !== 'undefined')
94-
&& (this.listId !== null);
94+
const anyListId =
95+
(typeof this.listId !== 'undefined') && (this.listId !== null);
9596
if (anyListId && this.spec) {
9697
if (this.listSubs) {
9798
this.subs.remove(this.listSubs);
9899
this.listSubs.unsubscribe();
99100
}
100101

101-
const cs$ = this.spec.getList(this.listId);
102-
this.listSubs = cs$ && cs$.subscribe(l => {
103-
if (l) {
104-
this.childrenSubject$.next(l);
105-
this.children = l;
106-
}
107-
});
108-
109-
this.subs.add(this.listSubs);
102+
if (this.spec.getList) {
103+
const cs$ = this.spec.getList(this.listId);
104+
this.listSubs = cs$ && cs$.subscribe(l => {
105+
if (l) {
106+
this.childrenSubject$.next(l);
107+
this.children = l;
108+
this.cdr.markForCheck();
109+
}
110+
});
111+
112+
this.subs.add(this.listSubs);
113+
}
110114
}
111115
}
112116

packages/angular-skyhook-card-list/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Observable } from 'rxjs';
22

33
export interface SortableSpec<Data, Type = string|symbol> {
44
trackBy: (data: Data) => any;
5-
getList: (listId: any) => Observable<Iterable<Data> | undefined>;
5+
getList?: (listId: any) => Observable<Iterable<Data> | undefined>;
66
canDrag?: (data: Data, listId: any) => boolean;
77
canDrop?: (item: DraggedItem<Data, Type>) => boolean;
88
isDragging?: (ground: Data, inFlight: DraggedItem<Data, Type>) => boolean;

packages/examples/src/app/sortable/simple/container.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Component } from "@angular/core";
44
selector: 'simple-sortable-container',
55
template:
66
`
7+
<app-example-link path="sortable/simple"></app-example-link>
78
<p> Note: uses unreleased code. </p>
89
910
<p> This example is like the 'Basic Sortable', except you don't have to
Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
.flex { display: flex; }
2-
.flex > * { flex-grow: 1; flex-shrink: 0; min-width: 0; }
3-
.card { min-width: 0; width: 100%; max-width: 300px; margin: 4px; border: 1px dashed #333; }
4-
.card { cursor: move; }
5-
pre { margin: 0; }
6-
.placeholder pre { opacity: 0.4; background: #eee; }
7-
.list--right pre { color: #a70000; }
8-
.list--right pre { background: rgba(255, 0, 0, 0.1); }
1+
.person {
2+
min-width: 0;
3+
width: 100%;
4+
max-width: 300px;
5+
margin: 4px;
6+
border: 1px dashed #333;
7+
cursor: move;
8+
}
9+
pre {
10+
margin: 0;
11+
color: #1111a7;
12+
background: rgba(30, 30, 255, 0.1);
13+
}
14+
.person--placeholder pre {
15+
opacity: 0.4;
16+
background: #eee;
17+
}
18+

packages/examples/src/app/sortable/simple/simple.component.ts

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ interface SimpleData {
1616
<skyhook-card-list class="list"
1717
cardListType="SIMPLE"
1818
cardListId="simple-demo"
19+
[cardListChildren]="tempList"
1920
[cardListSpec]="simpleSpec">
2021
2122
<ng-template cardTemplate let-context>
2223
<!-- cardRenderer configures a DragSource for you, but you have to attach it. -->
23-
<div class="card"
24+
<div class="person"
2425
[cardRenderer]="context"
2526
#render="cardRenderer"
26-
[class.placeholder]="render.isDragging$|async"
27+
[class.person--placeholder]="render.isDragging$|async"
2728
[dragSource]="render.source"> <!-- <<< attached here! -->
2829
2930
<pre>{{ render.data.name | json }}</pre>
@@ -43,10 +44,8 @@ export class SimpleComponent {
4344
{ id: 5, name: faker.name.firstName() },
4445
];
4546

46-
// BehaviorSubject is great for simple pieces of changing state.
47-
// It will happily replay the latest value to new subscribers, and behaves a bit
48-
// like an @ngrx/store does.
49-
list$ = new BehaviorSubject(this.list);
47+
// for holding modifications while dragging
48+
tempList: SimpleData[] = this.list;
5049

5150
move(item: DraggedItem<SimpleData>) {
5251
// shallow clone the list
@@ -62,21 +61,14 @@ export class SimpleComponent {
6261
simpleSpec: SortableSpec<SimpleData> = {
6362
// required.
6463
trackBy: x => x.id,
65-
// required. MUST return an Observable.
66-
// conceptually, this.list$ is in flux, but this.list is the 'saved' version.
67-
getList: _listId => this.list$,
68-
hover: (item) => {
69-
// fire off a new list$ but don't save yet
70-
this.list$.next(this.move(item));
64+
hover: item => { // don't save yet
65+
this.tempList = this.move(item)
7166
},
72-
drop: (item) => {
73-
// 'save the changes'
74-
this.list = this.move(item);
75-
this.list$.next(this.list);
67+
drop: item => { // save the changes
68+
this.tempList = this.list = this.move(item);
7669
},
77-
endDrag: item => {
78-
// revert
79-
this.list$.next(this.list);
70+
endDrag: item => { // revert
71+
this.tempList = this.list;
8072
}
8173
}
8274

0 commit comments

Comments
 (0)