-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(table): allow data input to be array, stream #9489
feat(table): allow data input to be array, stream #9489
Conversation
b1727c3
to
7c12036
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm excited for this! I think it'll reduce a lot of first-try friction.
src/cdk/table/table.spec.ts
Outdated
expectedRender.push(['a_4', 'b_4', 'c_4']); | ||
stream.next(data); | ||
dataInputFixture.detectChanges(); | ||
expectTableToMatchContent(dataInputTableElement, expectedRender); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there value in also testing the expected behavior around table.renderRows()
with the stream input?
Particularly, I'm curious what the expected behavior is after
data.push({a: 'a_4', b: 'b_4', c: 'c_4'});
// Note: not advancing BehaviorSubject
dataInputComponent.table.renderRows();
dataInputFixture.detectChanges();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion, I do think there's value in making sure that the renderRows will work like this. I expect they'll be a subset of users who use a stream to provide some array but would like to still manipulate the array and not think about emitting again
src/cdk/table/table.ts
Outdated
* a header row and data rows. Updates the rows when new data is provided by the data source. | ||
* A data table that renders a header row and data rows. Uses the dataSource input to determine | ||
* the data to be rendered. The data can be provided either as a data array, a stream that emits | ||
* the data array to render, or a DataSource that provides a stream that emits the data array to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider replacing 'stream' with 'Observable' or 'Observable stream' here and throughout, for clarity. Though, 'stream' may be self explanatory given the dataSource
property will show Observable<T[]>
in the docs.
src/cdk/table/table.ts
Outdated
* Sets the table's source of data, which can be provided in three ways (in order of complexity): | ||
* - Simple data array (each object represents one table row) | ||
* - Stream that emits a data array each time the array changes | ||
* - `DataSource` object that implements the connect/disconnect interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nit: inconsistent periods
src/lib/table/table.md
Outdated
input. The table will take the array and render a row for each object in the data array. | ||
|
||
```html | ||
<mat-table [data]=”myDataArray”> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dataSource
here and above? Or was an alias added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it should be dataSource
src/lib/table/table.md
Outdated
array. Instead, when objects are added, removed, or moved on the data array, you can trigger an | ||
update to the table's rendered rows by calling its `renderRows()` function. | ||
|
||
See the section "Alternative ways to provide data" for more approaches to providing data to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to add a link so the toc will pick it up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think they'll be a link we can use but not sure if we've done that yet in our docs. We should make sure that's supported or easy to do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TOC will link to section headers, but any links in the content have to be manually added.
I would also rephrase this paragraph to something like
While an array is the _simplest_ way to bind data into the data source, it is also
the most limited. For more complex applications, using a `DataSource` instance
is recommended. See xxx below for more information.
src/lib/table/table.md
Outdated
|
||
Also, another approach to providing data is by implementing a `DataSource`. This is simply | ||
an interface that has two functions: `connect` and `disconnect`. After passing a DataSource to the | ||
table, the table will call `connect()` to receive a stream that emits the data array that should be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: consistent use of parenthesis for methods
src/lib/table/table.md
Outdated
include/exclude columns dynamically. | ||
|
||
### Alternative ways to provide data | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a little blurb to refresh the reader of what the original option is
Alternative ways to provide data
The simplest way to provide data to your table is by passing a data array. More complex use-cases may benefit from a more flexible approach. (or something like that)
Observable stream of data arrays
...
DataSource
...
src/lib/table/table.md
Outdated
to clean up any subscriptions that may have been registered during the `connect` process. | ||
|
||
The benefit to creating a `DataSource` class is that it can decouple rendering logic from your | ||
component and keep it encapsulated in a separate class (e.g. sorting, filtering, pagination, e.g.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be helpful to eventually have an example for each of these that is just like table-basic
, but using the alternative approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 I think this would be useful to demonstrate the differences, I'll make an issue following this PR getting merged
I'm excited as well, I think this will help make things a lot easier and reduce the learning curve of the table. Next for me is to add some kind of |
src/cdk/table/table.ts
Outdated
@@ -153,17 +157,32 @@ export class CdkTable<T> implements CollectionViewer, OnInit, AfterContentChecke | |||
private _trackByFn: TrackByFunction<T>; | |||
|
|||
/** | |||
* Provides a stream containing the latest data array to render. Influenced by the table's | |||
* stream of view window (what rows are currently on screen). | |||
* Sets the table's source of data, which can be provided in three ways (in order of complexity): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Omit "Sets", since this is a property, not a method
src/cdk/table/table.ts
Outdated
* | ||
* If a data array is provided, the table must be notified when the array's objects are | ||
* added, removed, or moved. This can be done by calling the `renderRows()` function which will | ||
* render the diff since the last table render. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about when the array reference changes?
src/cdk/table/table.ts
Outdated
* render the diff since the last table render. | ||
* | ||
* When providing an Observable stream, the table will trigger an update automatically when the | ||
* stream emits a new array of data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Omit "a new array of data"?
src/cdk/table/table.ts
Outdated
* directly, you will need to call this function whenever data in the provided array is | ||
* added/removed/moved in-place. | ||
*/ | ||
renderRows() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's your thinking on renderRows
vs. refresh
or render
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong opinion really, I'm open to any of those. Maybe refresh
sounds more approachable for users to call?
src/cdk/table/table.ts
Outdated
* Checks for differences in the data since the last diff to perform only the necessary | ||
* changes (add/remove/move rows). | ||
* | ||
* If the table's data source is a DataSource or Observable, this will be invoked each time the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"invoked automatically"
src/lib/table/table.md
Outdated
array. Instead, when objects are added, removed, or moved on the data array, you can trigger an | ||
update to the table's rendered rows by calling its `renderRows()` function. | ||
|
||
See the section "Alternative ways to provide data" for more approaches to providing data to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TOC will link to section headers, but any links in the content have to be manually added.
I would also rephrase this paragraph to something like
While an array is the _simplest_ way to bind data into the data source, it is also
the most limited. For more complex applications, using a `DataSource` instance
is recommended. See xxx below for more information.
src/lib/table/table.md
Outdated
|
||
Start by writing your table's column definitions. Each column definition should be given a unique | ||
name and contain the content for its header and row cells. | ||
#### 2. Define the table's columns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to say "column templates" (and "row templates" below)? Having "Define the table's rows" feels weird since the data drives the rows, you're just specifying the bindings.
src/lib/table/table.md
Outdated
This means that by changing your column list provided to the rows, you can easily re-order and | ||
include/exclude columns dynamically. | ||
|
||
### Alternative ways to provide data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say "Advanced data sources"
src/lib/table/table.md
Outdated
|
||
#### DataSource | ||
|
||
Also, another approach to providing data is by implementing a `DataSource`. This is simply |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change this first sentence to something like
For most real-world applications, providing the table a `DataSource` instance will be the best way to manage data.
It's also a base class, not an interface. I would put the "Why use a data source" bits before the "what is it" bits; we should say something like "The DataSource
is meant to serve a place to encapsulate any sorting, filtering, pagination, and data retrieval logic specific to the application."
mutating the data provided to the table according to their outputs. | ||
|
||
To simplify the use case of having a table that can sort, paginate, and filter an array of data, | ||
the Angular Material library comes with a `MatTableDataSource` that has already implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still want to rename this to ClientArrayDataSource
(or ClientDataSource
or ArrayDataSource
or even SimpleDataSource
)
My problem with the current name is that it implies that it is the way to provide data for a <mat-table>
, wich may lead people to think that the table doesn't support server side sorting/pagination/filtering, or even just other kinds of filtering than search.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'm open to renaming. We should brainstorm offline to figure out the best name
179b9e3
to
018735f
Compare
Ready for another round of review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments still seem unresolved
Alright, mostly sure now that it's good. Had an odd time merging conflicts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
701d6b7
to
36f6aff
Compare
* feat(table): allow data input to be array, stream * comments * fix connect function * fix connect function v2 * fix demo imports
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Removes requirement of implementing/using a
DataSource
to use the table. Instead, users can directly provide a data array or stream of data arrays directly as the data source.@willshowell Can you take a look, especially the revamped docs?
Closes #8227