@iyulab/flex-table 0.57.0 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +7 -5
- package/dist/array/index.js +23 -19
- package/dist/array/source.d.ts +6 -0
- package/dist/array/types.d.ts +4 -0
- package/dist/odata/controller.d.ts +4 -0
- package/dist/odata/index.js +2 -2
- package/dist/odata/source.d.ts +4 -0
- package/dist/odata/types.d.ts +2 -0
- package/dist/react.js +20 -13
- package/dist/{source--q5s2Oti.js → source-DOue0Ti3.js} +13 -2
- package/package.json +1 -1
- package/skills/iyulab-flex-table/references/react.md +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.58.0] - 2026-10-07
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Page size is source state.** `createODataSource` / `createArraySource` state (and `useODataSource` /
|
|
8
|
+
`useArraySource`) carries `pageSize`, and `setPageSize(size)` changes it and goes back to page 0 — a pager's «rows per
|
|
9
|
+
page» had no way to reach the source. An `update` (or a render) that passes the same `pageSize` option again keeps the
|
|
10
|
+
size `setPageSize` set; a changed option value takes effect.
|
|
11
|
+
- **`ODataSourceController` and `ArraySourceController` take an existing source** —
|
|
12
|
+
`new ODataSourceController(this, source)` — so several elements (a table, a pager) share one source. Created from a
|
|
13
|
+
URL (or rows) as before.
|
|
14
|
+
|
|
3
15
|
## [0.57.0] - 2026-10-07
|
|
4
16
|
|
|
5
17
|
### Changed (breaking)
|
package/README.md
CHANGED
|
@@ -830,6 +830,7 @@ The hook returns:
|
|
|
830
830
|
| `loading` | A request is in flight, or none has answered yet (true from the first render until the first response settles, and while `enabled: false`) |
|
|
831
831
|
| `error` | The last failed request, or `null`: `{ message, status?, code?, details?, body? }`. **Pass it to the table** (`error={source.error}`) or render `error.message` yourself — a failed request otherwise leaves the grid silently empty. Branch on `status` (HTTP), `code` (the server's rejection code, OData `error.code`) and `details` (OData `error.details`); `body` is the parsed response (or its text). A failure with no response — a network error, or a `@odata.nextLink` the hook refused — has a `message` only |
|
|
832
832
|
| `page` / `setPage` | Zero-based page index |
|
|
833
|
+
| `pageSize` / `setPageSize` | Rows per page — starts at the `pageSize` option (20); `setPageSize` changes it and goes back to page 0. Passing the same `pageSize` option again on the next render keeps the size `setPageSize` set |
|
|
833
834
|
| `sortCriteria` / `onSortChange` | Bind `onSortChange` to the table's `sort-change` event |
|
|
834
835
|
| `search` / `setSearch` | Current search term and its setter (resets to page 0) |
|
|
835
836
|
| `refresh` | Re-run the current request |
|
|
@@ -880,16 +881,17 @@ off(); // the last unsu
|
|
|
880
881
|
|
|
881
882
|
| Member | Description |
|
|
882
883
|
|---|---|
|
|
883
|
-
| `getState()` | `{ data, totalCount, loading, error, page, sortCriteria, search }` — the same fields the hook returns. A new object only when something changed |
|
|
884
|
+
| `getState()` | `{ data, totalCount, loading, error, page, pageSize, sortCriteria, search }` — the same fields the hook returns. A new object only when something changed |
|
|
884
885
|
| `subscribe(listener)` | Called on every change; returns the unsubscribe function. Requests go out only while someone is subscribed |
|
|
885
886
|
| `setPage(page)` | Zero-based |
|
|
887
|
+
| `setPageSize(size)` | Rows per page; goes back to page 0 |
|
|
886
888
|
| `setSort(criteria)` / `setSearch(term)` | Change the sort or search and go back to page 0 |
|
|
887
889
|
| `refresh()` | Re-read with the same conditions (nothing while `enabled: false`) |
|
|
888
|
-
| `update(url, options)` | New options. Only a changed request re-reads; a changed `fixedFilter` value goes back to page 0; `initial*` are read at creation only |
|
|
890
|
+
| `update(url, options)` | New options. Only a changed request re-reads; a changed `fixedFilter` value goes back to page 0; a changed `pageSize` value takes effect (page 0), the same value again keeps the size `setPageSize` set; `initial*` are read at creation only |
|
|
889
891
|
|
|
890
892
|
Changes made in the same tick become one request with the final conditions, so `setSearch` followed by `setPage` does not send the intermediate one.
|
|
891
893
|
|
|
892
|
-
For a Lit element, `ODataSourceController` ties a source to the element's lifecycle — it subscribes when the element connects, cancels when it disconnects, and re-renders it on every change:
|
|
894
|
+
For a Lit element, `ODataSourceController` ties a source to the element's lifecycle — it subscribes when the element connects, cancels when it disconnects, and re-renders it on every change. Give it a URL to create the source, or **a source you already have** (`new ODataSourceController(this, source)`) so several elements — a table, a pager — share one:
|
|
893
895
|
|
|
894
896
|
```ts
|
|
895
897
|
import { LitElement, html } from 'lit';
|
|
@@ -952,8 +954,8 @@ count after search (not a server-reported total), and `loading`/`error` are alwa
|
|
|
952
954
|
"refresh" button wired unconditionally against either hook doesn't need a branch.
|
|
953
955
|
|
|
954
956
|
Without React, `createArraySource(rows, options)` (`@iyulab/flex-table/array`) is the same source with the same
|
|
955
|
-
members as `createODataSource` — `getState()`, `subscribe()`, `setPage`, `setSort`, `setSearch`, `refresh` (no-op) —
|
|
956
|
-
plus `update(rows, options)` when the rows change. `ArraySourceController` binds it to a Lit element:
|
|
957
|
+
members as `createODataSource` — `getState()`, `subscribe()`, `setPage`, `setPageSize`, `setSort`, `setSearch`, `refresh` (no-op) —
|
|
958
|
+
plus `update(rows, options)` when the rows change. `ArraySourceController` binds it to a Lit element (from rows, or an existing source):
|
|
957
959
|
|
|
958
960
|
```ts
|
|
959
961
|
import { LitElement } from 'lit';
|
package/dist/array/index.js
CHANGED
|
@@ -7,55 +7,59 @@ function n(n, r = {}) {
|
|
|
7
7
|
initialPage: r.initialPage ?? 0,
|
|
8
8
|
initialSearch: r.initialSearch ?? "",
|
|
9
9
|
initialSort: r.initialSort
|
|
10
|
-
}), s = o.page, c = o.sortCriteria, l = o.search, u =
|
|
11
|
-
function
|
|
12
|
-
let e =
|
|
10
|
+
}), s = o.page, c = o.sortCriteria, l = o.search, u = r.pageSize ?? 20, d = p(), f = /* @__PURE__ */ new Set();
|
|
11
|
+
function p() {
|
|
12
|
+
let e = t(i, {
|
|
13
13
|
search: l,
|
|
14
14
|
sortCriteria: c,
|
|
15
15
|
page: s,
|
|
16
|
-
pageSize:
|
|
16
|
+
pageSize: u,
|
|
17
17
|
columns: a.columns,
|
|
18
18
|
searchFields: a.searchFields
|
|
19
|
-
}),
|
|
20
|
-
return s >
|
|
21
|
-
data:
|
|
22
|
-
totalCount:
|
|
19
|
+
}), n = e.totalCount === 0 ? 0 : Math.ceil(e.totalCount / u) - 1;
|
|
20
|
+
return s > n && (s = n), {
|
|
21
|
+
data: e.data,
|
|
22
|
+
totalCount: e.totalCount,
|
|
23
23
|
loading: !1,
|
|
24
24
|
error: null,
|
|
25
25
|
page: s,
|
|
26
|
+
pageSize: u,
|
|
26
27
|
sortCriteria: c,
|
|
27
28
|
search: l
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
for (let e of [...
|
|
31
|
+
function m() {
|
|
32
|
+
d = p();
|
|
33
|
+
for (let e of [...f]) e();
|
|
33
34
|
}
|
|
34
35
|
return {
|
|
35
|
-
getState: () =>
|
|
36
|
+
getState: () => d,
|
|
36
37
|
subscribe(e) {
|
|
37
|
-
return
|
|
38
|
-
|
|
38
|
+
return f.add(e), () => {
|
|
39
|
+
f.delete(e);
|
|
39
40
|
};
|
|
40
41
|
},
|
|
41
42
|
setPage(e) {
|
|
42
|
-
s = e,
|
|
43
|
+
s = e, m();
|
|
44
|
+
},
|
|
45
|
+
setPageSize(e) {
|
|
46
|
+
e !== u && (u = e, s = 0, m());
|
|
43
47
|
},
|
|
44
48
|
setSort(e) {
|
|
45
|
-
c = e, s = 0,
|
|
49
|
+
c = e, s = 0, m();
|
|
46
50
|
},
|
|
47
51
|
setSearch(e) {
|
|
48
|
-
l = e, s = 0,
|
|
52
|
+
l = e, s = 0, m();
|
|
49
53
|
},
|
|
50
54
|
refresh() {},
|
|
51
55
|
update(e, t = {}) {
|
|
52
|
-
i = e, a = t,
|
|
56
|
+
t.pageSize !== void 0 && t.pageSize !== a.pageSize && t.pageSize !== u && (u = t.pageSize, s = 0), i = e, a = t, m();
|
|
53
57
|
}
|
|
54
58
|
};
|
|
55
59
|
}
|
|
56
60
|
var r = class {
|
|
57
61
|
constructor(e, t, r = {}) {
|
|
58
|
-
this.host = e, this.source = n(t, r), e.addController(this);
|
|
62
|
+
this.host = e, this.source = Array.isArray(t) ? n(t, r) : t, e.addController(this);
|
|
59
63
|
}
|
|
60
64
|
get state() {
|
|
61
65
|
return this.source.getState();
|
package/dist/array/source.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface ArraySource<T> {
|
|
|
13
13
|
subscribe(listener: () => void): () => void;
|
|
14
14
|
/** 0-based 페이지로 옮긴다(범위를 넘으면 마지막 페이지). */
|
|
15
15
|
setPage(page: number): void;
|
|
16
|
+
/** 페이지 크기를 바꾸고 첫 장으로 간다. */
|
|
17
|
+
setPageSize(size: number): void;
|
|
16
18
|
/** 정렬을 바꾸고 첫 장으로 간다. */
|
|
17
19
|
setSort(criteria: SortCriteria[]): void;
|
|
18
20
|
/** 검색어를 바꾸고 첫 장으로 간다. */
|
|
@@ -35,6 +37,10 @@ export declare class ArraySourceController<T extends DataRow = DataRow> implemen
|
|
|
35
37
|
/** 소스 — 조작(`setPage`·`setSort`·`setSearch`·`update`)은 이것으로 한다. */
|
|
36
38
|
readonly source: ArraySource<T>;
|
|
37
39
|
private unsubscribe?;
|
|
40
|
+
/**
|
|
41
|
+
* 행으로 소스를 만들거나, **이미 있는 소스**를 받는다 — 같은 소스를 여러 요소(표 · 페이저 · 목록 골격)가 함께 쓴다.
|
|
42
|
+
*/
|
|
43
|
+
constructor(host: ReactiveControllerHost, source: ArraySource<T>);
|
|
38
44
|
constructor(host: ReactiveControllerHost, data: T[], options?: ArraySourceOptions<T>);
|
|
39
45
|
/** 현재 상태. */
|
|
40
46
|
get state(): ODataSourceState<T>;
|
package/dist/array/types.d.ts
CHANGED
|
@@ -40,6 +40,10 @@ export interface UseArraySourceResult<T> {
|
|
|
40
40
|
error: SourceError | null;
|
|
41
41
|
page: number;
|
|
42
42
|
setPage: (page: number) => void;
|
|
43
|
+
/** 한 페이지의 행 수 — `pageSize` 옵션으로 시작하고 `setPageSize` 로 바뀐다. */
|
|
44
|
+
pageSize: number;
|
|
45
|
+
/** 페이지 크기를 바꾸고 첫 장으로 간다. */
|
|
46
|
+
setPageSize: (size: number) => void;
|
|
43
47
|
sortCriteria: SortCriteria[];
|
|
44
48
|
onSortChange: (e: CustomEvent) => void;
|
|
45
49
|
setSearch: (term: string) => void;
|
|
@@ -21,6 +21,10 @@ export declare class ODataSourceController<T = Record<string, unknown>> implemen
|
|
|
21
21
|
/** 소스 — 조작(`setPage`·`setSort`·`setSearch`·`refresh`·`update`)은 이것으로 한다. */
|
|
22
22
|
readonly source: ODataSource<T>;
|
|
23
23
|
private unsubscribe?;
|
|
24
|
+
/**
|
|
25
|
+
* 주소로 소스를 만들거나, **이미 있는 소스**를 받는다 — 같은 소스를 여러 요소(표 · 페이저 · 목록 골격)가 함께 쓴다.
|
|
26
|
+
*/
|
|
27
|
+
constructor(host: ReactiveControllerHost, source: ODataSource<T>);
|
|
24
28
|
constructor(host: ReactiveControllerHost, url: string, options?: ODataSourceOptions);
|
|
25
29
|
/** 현재 상태. */
|
|
26
30
|
get state(): ODataSourceState<T>;
|
package/dist/odata/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as e, r as t, t as n } from "../query-Dw4iO0ir.js";
|
|
2
|
-
import { t as r } from "../source
|
|
2
|
+
import { t as r } from "../source-DOue0Ti3.js";
|
|
3
3
|
//#region src/odata/controller.ts
|
|
4
4
|
var i = class {
|
|
5
5
|
constructor(e, t, n = {}) {
|
|
6
|
-
this.host = e, this.source = r(t, n), e.addController(this);
|
|
6
|
+
this.host = e, this.source = typeof t == "string" ? r(t, n) : t, e.addController(this);
|
|
7
7
|
}
|
|
8
8
|
get state() {
|
|
9
9
|
return this.source.getState();
|
package/dist/odata/source.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ export interface ODataSourceState<T> {
|
|
|
50
50
|
error: SourceError | null;
|
|
51
51
|
/** 0-based. */
|
|
52
52
|
page: number;
|
|
53
|
+
/** 한 페이지의 행 수 — `pageSize` 옵션으로 시작하고(기본 20) `setPageSize` 로 바뀐다. */
|
|
54
|
+
pageSize: number;
|
|
53
55
|
sortCriteria: SortCriteria[];
|
|
54
56
|
search: string;
|
|
55
57
|
}
|
|
@@ -66,6 +68,8 @@ export interface ODataSource<T> {
|
|
|
66
68
|
subscribe(listener: () => void): () => void;
|
|
67
69
|
/** 0-based 페이지로 옮긴다. */
|
|
68
70
|
setPage(page: number): void;
|
|
71
|
+
/** 페이지 크기를 바꾸고 첫 장으로 간다(페이저의 «페이지당 행 수»). */
|
|
72
|
+
setPageSize(size: number): void;
|
|
69
73
|
/** 정렬을 바꾸고 첫 장으로 간다. */
|
|
70
74
|
setSort(criteria: SortCriteria[]): void;
|
|
71
75
|
/** 검색어를 바꾸고 첫 장으로 간다. */
|
package/dist/odata/types.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { ODataSourceOptions, ODataSourceState } from './source.js';
|
|
|
4
4
|
export type UseODataSourceOptions = ODataSourceOptions;
|
|
5
5
|
export interface UseODataSourceResult<T> extends ODataSourceState<T> {
|
|
6
6
|
setPage: (page: number) => void;
|
|
7
|
+
/** 페이지 크기를 바꾸고 첫 장으로 간다. */
|
|
8
|
+
setPageSize: (size: number) => void;
|
|
7
9
|
/** flex-table 의 `sort-change` 를 받는다(`detail.criteria`) — 정렬을 바꾸고 첫 장으로 간다. */
|
|
8
10
|
onSortChange: (e: CustomEvent) => void;
|
|
9
11
|
/** 검색어를 바꾸고 첫 장으로 간다. */
|
package/dist/react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./flex-table-B1W8VEBa.js";
|
|
2
2
|
import { i as t } from "./query-Dw4iO0ir.js";
|
|
3
|
-
import { t as n } from "./source
|
|
3
|
+
import { t as n } from "./source-DOue0Ti3.js";
|
|
4
4
|
import { t as r } from "./view-DiLr-TdY.js";
|
|
5
5
|
import i, { useCallback as a, useEffect as o, useMemo as s, useState as c, useSyncExternalStore as l } from "react";
|
|
6
6
|
import { createComponent as u } from "@lit/react";
|
|
@@ -17,6 +17,7 @@ function d(e, t = {}) {
|
|
|
17
17
|
return {
|
|
18
18
|
...i,
|
|
19
19
|
setPage: r.setPage,
|
|
20
|
+
setPageSize: r.setPageSize,
|
|
20
21
|
onSortChange: s,
|
|
21
22
|
setSearch: r.setSearch,
|
|
22
23
|
refresh: r.refresh
|
|
@@ -30,16 +31,20 @@ function f(e, n = {}) {
|
|
|
30
31
|
initialPage: l,
|
|
31
32
|
initialSearch: u,
|
|
32
33
|
initialSort: d
|
|
33
|
-
}), [h, g] = c(m.page), [_, v] = c(m.sortCriteria), [y, b] = c(m.search), x =
|
|
34
|
+
}), [h, g] = c(m.page), [_, v] = c(m.sortCriteria), [y, b] = c(m.search), [x, S] = c(i), [C, w] = c(i);
|
|
35
|
+
i !== C && (w(i), S(i), g(0));
|
|
36
|
+
let T = a((e) => {
|
|
37
|
+
S(e), g(0);
|
|
38
|
+
}, []), E = a((e) => {
|
|
34
39
|
b(e), g(0);
|
|
35
|
-
}, []),
|
|
40
|
+
}, []), D = a((e) => {
|
|
36
41
|
let t = e.detail?.criteria;
|
|
37
42
|
t && (v(t), g(0));
|
|
38
|
-
}, []),
|
|
43
|
+
}, []), O = a(() => {}, []), { data: k, totalCount: A } = s(() => r(e, {
|
|
39
44
|
search: y,
|
|
40
45
|
sortCriteria: _,
|
|
41
46
|
page: h,
|
|
42
|
-
pageSize:
|
|
47
|
+
pageSize: x,
|
|
43
48
|
columns: f,
|
|
44
49
|
searchFields: p
|
|
45
50
|
}), [
|
|
@@ -47,22 +52,24 @@ function f(e, n = {}) {
|
|
|
47
52
|
y,
|
|
48
53
|
_,
|
|
49
54
|
h,
|
|
50
|
-
|
|
55
|
+
x,
|
|
51
56
|
f,
|
|
52
57
|
p
|
|
53
|
-
]),
|
|
54
|
-
return h >
|
|
55
|
-
data:
|
|
56
|
-
totalCount:
|
|
58
|
+
]), j = A === 0 ? 0 : Math.ceil(A / x) - 1;
|
|
59
|
+
return h > j && g(j), {
|
|
60
|
+
data: k,
|
|
61
|
+
totalCount: A,
|
|
57
62
|
loading: !1,
|
|
58
63
|
error: null,
|
|
59
64
|
page: h,
|
|
60
65
|
setPage: g,
|
|
66
|
+
pageSize: x,
|
|
67
|
+
setPageSize: T,
|
|
61
68
|
sortCriteria: _,
|
|
62
|
-
onSortChange:
|
|
69
|
+
onSortChange: D,
|
|
63
70
|
search: y,
|
|
64
|
-
setSearch:
|
|
65
|
-
refresh:
|
|
71
|
+
setSearch: E,
|
|
72
|
+
refresh: O
|
|
66
73
|
};
|
|
67
74
|
}
|
|
68
75
|
var p = u({
|
|
@@ -54,6 +54,7 @@ function c(e, i = {}) {
|
|
|
54
54
|
loading: !0,
|
|
55
55
|
error: null,
|
|
56
56
|
page: f.page,
|
|
57
|
+
pageSize: i.pageSize ?? 20,
|
|
57
58
|
sortCriteria: f.sortCriteria,
|
|
58
59
|
search: f.search
|
|
59
60
|
}, m = x(), h = /* @__PURE__ */ new Set(), g = null, _ = !1, v = null;
|
|
@@ -61,7 +62,7 @@ function c(e, i = {}) {
|
|
|
61
62
|
return u.enabled ?? !0;
|
|
62
63
|
}
|
|
63
64
|
function b() {
|
|
64
|
-
return
|
|
65
|
+
return p.pageSize;
|
|
65
66
|
}
|
|
66
67
|
function x() {
|
|
67
68
|
return {
|
|
@@ -181,6 +182,12 @@ function c(e, i = {}) {
|
|
|
181
182
|
setPage(e) {
|
|
182
183
|
S({ page: e }), T();
|
|
183
184
|
},
|
|
185
|
+
setPageSize(e) {
|
|
186
|
+
e !== p.pageSize && (S({
|
|
187
|
+
pageSize: e,
|
|
188
|
+
page: 0
|
|
189
|
+
}), T());
|
|
190
|
+
},
|
|
184
191
|
setSort(e) {
|
|
185
192
|
S({
|
|
186
193
|
sortCriteria: e,
|
|
@@ -197,10 +204,14 @@ function c(e, i = {}) {
|
|
|
197
204
|
y() && (v = null, T());
|
|
198
205
|
},
|
|
199
206
|
update(e, t = {}) {
|
|
200
|
-
let n = l(t.fixedFilter), r = n !== d;
|
|
207
|
+
let n = l(t.fixedFilter), r = n !== d, i = t.pageSize !== void 0 && t.pageSize !== u.pageSize;
|
|
201
208
|
c = e, u = t, d = n, r && (p = {
|
|
202
209
|
...p,
|
|
203
210
|
page: 0
|
|
211
|
+
}), i && t.pageSize !== p.pageSize && (p = {
|
|
212
|
+
...p,
|
|
213
|
+
pageSize: t.pageSize,
|
|
214
|
+
page: 0
|
|
204
215
|
}), C(), T();
|
|
205
216
|
}
|
|
206
217
|
};
|
package/package.json
CHANGED
|
@@ -110,6 +110,7 @@ function Orders() {
|
|
|
110
110
|
| `loading` | Request in flight, or no answer yet (true from the first render until the first response settles, and while `enabled: false`) — so `!loading && totalCount === 0` means "no results" |
|
|
111
111
|
| `error` | `SourceError \| null` — `{ message, status?, code?, details?, body?, cause? }`; pass it to the table (`error`) or render `error.message`; branch on `status` / `code` (OData `error.code`). `message` is the server's sentence when it sent one; otherwise this package's, in the `flexTableLocale` language — `requestFailed` (`Request failed ({status})`) when a response came back, `networkFailed` when none did (the transport's exception is in `cause`) |
|
|
112
112
|
| `page`, `setPage` | Zero-based |
|
|
113
|
+
| `pageSize`, `setPageSize` | Rows per page (the `pageSize` option, then `setPageSize` — resets to page 0) |
|
|
113
114
|
| `sortCriteria`, `onSortChange` | Pass `onSortChange` to the table's `sort-change` (resets to page 0) |
|
|
114
115
|
| `search`, `setSearch` | Literal text (resets to page 0) |
|
|
115
116
|
| `refresh` | Re-run the current request |
|
|
@@ -158,9 +159,9 @@ Differences: `totalCount` is the count after search, `loading` is always `false`
|
|
|
158
159
|
|
|
159
160
|
`useODataSource` adapts a framework-neutral source with the same options and state:
|
|
160
161
|
`createODataSource(url, options)` → `getState()` · `subscribe(listener)` (the first subscriber starts loading, the last
|
|
161
|
-
unsubscribe cancels) · `setPage` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)`. Changes in one
|
|
162
|
+
unsubscribe cancels) · `setPage` · `setPageSize` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)`. Changes in one
|
|
162
163
|
tick become one request. For Lit, `ODataSourceController` subscribes on connect, cancels on disconnect and re-renders
|
|
163
|
-
the host:
|
|
164
|
+
the host — from a URL, or from a source you already have (`new ODataSourceController(this, source)`, so a table and a pager share it):
|
|
164
165
|
|
|
165
166
|
```ts
|
|
166
167
|
import { LitElement, html } from 'lit';
|