ui: Thread through data-source invalidate method (#13710)

* ui: Thread through data-source invalidate method

* Remove old invalidating state
This commit is contained in:
John Cowen 2022-07-14 09:30:35 +01:00 committed by GitHub
parent 65eccb33ce
commit 6fce197908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 24 additions and 23 deletions

View File

@ -48,12 +48,13 @@ as |loader|>
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `src` | `String` | | The source to subscribe to updates to, this should map to a string based URI | | `src` | `String` | | The source to subscribe to updates to, this should map to a string based URI |
## Exports ## Exported API
| Name | Description | | Name | Type | Description |
| --- | --- | | --- | --- | --- |
| `data` | The loaded dataset once any data has been loaded successfully | | `data` | `object` | The loaded dataset once any data has been loaded successfully |
| `error` | The error thrown if an error is encountered whilst loading data | | `error` | `Error` |The error thrown if an error is encountered whilst loading data |
| `invalidate` | `function` | Invalidate the data represented by the DataLoader, therefore forcing a re-request of data for the DataLoader |
## Slots ## Slots

View File

@ -17,15 +17,9 @@ export default {
target: 'loading', target: 'loading',
}, },
], ],
INVALIDATE: [
{
target: 'invalidating',
},
],
}, },
states: { states: {
load: {}, load: {},
invalidating: {},
loading: { loading: {
on: { on: {
SUCCESS: { SUCCESS: {

View File

@ -7,7 +7,7 @@
{{#let (hash {{#let (hash
data=data data=data
error=error error=error
invalidate=(action "invalidate") invalidate=this.invalidate
dispatchError=(queue (action (mut error) value="error.errors.firstObject") (action dispatch "ERROR")) dispatchError=(queue (action (mut error) value="error.errors.firstObject") (action dispatch "ERROR"))
) as |api|}} ) as |api|}}
@ -17,7 +17,7 @@
{{! if we didn't specify any data}} {{! if we didn't specify any data}}
{{#if (not items)}} {{#if (not items)}}
{{! try and load the data if we aren't in an error state}} {{! try and load the data if we aren't in an error state}}
<State @notMatches={{array "error" "disconnected" "invalidating"}}> <State @notMatches={{array "error" "disconnected"}}>
{{! but only if we only asked for a single load and we are in loading state}} {{! but only if we only asked for a single load and we are in loading state}}
{{#if (and src (or (not once) (state-matches state "loading")))}} {{#if (and src (or (not once) (state-matches state "loading")))}}
<DataSource <DataSource
@ -25,7 +25,9 @@
@src={{src}} @src={{src}}
@onchange={{queue (action "change" value="data") (action dispatch "SUCCESS")}} @onchange={{queue (action "change" value="data") (action dispatch "SUCCESS")}}
@onerror={{api.dispatchError}} @onerror={{api.dispatchError}}
/> as |source|>
{{did-insert (set this 'invalidate' source.invalidate)}}
</DataSource>
{{/if}} {{/if}}
</State> </State>
{{/if}} {{/if}}
@ -47,7 +49,7 @@
{{/yield-slot}} {{/yield-slot}}
</State> </State>
<State @matches={{array "idle" "disconnected" "invalidating"}}> <State @matches={{array "idle" "disconnected"}}>
<State @matches="disconnected"> <State @matches="disconnected">
{{#if (not (eq error.status '401'))}} {{#if (not (eq error.status '401'))}}

View File

@ -1,6 +1,5 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { set } from '@ember/object'; import { set } from '@ember/object';
import { schedule } from '@ember/runloop';
import Slotted from 'block-slots'; import Slotted from 'block-slots';
import chart from './chart.xstate'; import chart from './chart.xstate';
@ -22,12 +21,6 @@ export default Component.extend(Slotted, {
this.dispatch('LOAD'); this.dispatch('LOAD');
}, },
actions: { actions: {
invalidate() {
this.dispatch('INVALIDATE');
schedule('afterRender', () => {
this.dispatch('LOAD');
});
},
isLoaded: function() { isLoaded: function() {
return typeof this.items !== 'undefined' || typeof this.src === 'undefined'; return typeof this.items !== 'undefined' || typeof this.src === 'undefined';
}, },

View File

@ -40,6 +40,14 @@ Please make sure you use the `uri` helper to specify src URIs, this ensures that
| `onchange` | `Function` | | The action to fire when the data changes. Emits an Event-like object with a `data` property containing the data. | | `onchange` | `Function` | | The action to fire when the data changes. Emits an Event-like object with a `data` property containing the data. |
| `onerror` | `Function` | | The action to fire when an error occurs. Emits ErrorEvent object with an `error` property containing the Error. | | `onerror` | `Function` | | The action to fire when an error occurs. Emits ErrorEvent object with an `error` property containing the Error. |
## Exported API
| Name | Type | Description |
| --- | --- | --- |
| `data` | `object` | The loaded dataset once any data has been loaded successfully |
| `error` | `Error` |The error thrown if an error is encountered whilst loading data |
| `invalidate` | `function` | Invalidate the data represented by the datasource, therefore forcing a re-request of data for the DataSource |
The component takes a `src` or an identifier (a uri) for some data and then emits `onchange` events whenever that data changes. If an error occurs whilst listening for data changes, an `onerror` event is emitted. The component takes a `src` or an identifier (a uri) for some data and then emits `onchange` events whenever that data changes. If an error occurs whilst listening for data changes, an `onerror` event is emitted.
Setting `@loading="lazy"` uses `IntersectionObserver` to activate/deactive event emitting until the `<DataSource />` element is displayed in the DOM. This means you can use CSS `display: none|block;` to control the loading and stopping loading of data for usage with CSS based tabs and such-like. Setting `@loading="lazy"` uses `IntersectionObserver` to activate/deactive event emitting until the `<DataSource />` element is displayed in the DOM. This means you can use CSS `display: none|block;` to control the loading and stopping loading of data for usage with CSS based tabs and such-like.

View File

@ -17,6 +17,7 @@
{{yield (hash {{yield (hash
data=this.data data=this.data
error=this.error error=this.error
invalidate=this.invalidate
Source=(if this.data Source=(if this.data
(component 'data-source' disabled=(not (eq this.error undefined))) (component 'data-source' disabled=(not (eq this.error undefined)))
'' ''

View File

@ -1,3 +1,4 @@
/* eslint no-console: ["error", { allow: ["debug"] }] */
import Component from '@glimmer/component'; import Component from '@glimmer/component';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
@ -179,6 +180,7 @@ export default class DataSource extends Component {
} }
} }
} }
@action @action
async invalidate() { async invalidate() {
this.source.readyState = 2; this.source.readyState = 2;
@ -186,7 +188,7 @@ export default class DataSource extends Component {
schedule('afterRender', () => { schedule('afterRender', () => {
// TODO: Support lazy data-sources by keeping a reference to $el // TODO: Support lazy data-sources by keeping a reference to $el
runInDebug(_ => runInDebug(_ =>
console.error( console.debug(
`Invalidation is only supported for non-lazy data sources. If you want to use this you should fixup support for lazy data sources` `Invalidation is only supported for non-lazy data sources. If you want to use this you should fixup support for lazy data sources`
) )
); );