简体   繁体   中英

How to subscribe to an async array in Angular with state management?

I have a dynamical list of items in my Angular app, a table of rows which look approximately like this:

 Product name [edit button]   Date changed  [delete]
 Product name [edit button]   Date changed  [delete]
 ....

I am using Elf to maintain the list (could use rxAngular for that matter, but it does not have built in support for lists of items, especially so lists of UI items. Didn't want to go for anything more sophisticated as NGXS/NGRX). I do use however, rxAngular for side effects only, this does not really matter for my question. When you click the [edit button] — you enter the "edit mode" — the Product name turns into an input box. After editing, Date changed changes appropriately.

(1) You don't see the problem with State Management until you attempt to add animation. The list of items is an observable, obtained from the Elf store (could have been any other store). As soon as you attempt to change anything, say enter the "edit mode", the store, according to the celebrated immutability principle, creates a new state. This means the list observable fires a new value, and since the list has changed, Angular has to redraw everything . With animation on, you see the rows dancing before they rearrange into the resulting state (all the rows are deleted, then new copies added). If only one property of the row is changed (say the Date changed ), then that property should re–render (which does not mean deletion and creation, just the change of content). How do you achieve that?

(2) It seems more and more to me that these State Management libraries are much more necessary in React than in Angular. Angular has change detection. So if you type something in the input box, the model will already have the value. Similarly, if you delete one row from a list, Angular will know that the other rows haven't changed. In this way, it does not need the store (for that matter, even the observables are not necessary here, but of course the list of items is async, so it will be an observable). One solution to using a store and not having the entire page re–render on any bit of change, is to use distinctUntilChanged() on every property that is being used in each row (product name, date etc ). This is done automatically if you use select() from the store. However, I don't know if that's possible to do when you have a list of items…

Easiest way to subscribe to your array is simply by using an async pipe.

In your HTML all you will have to do is {{yourObservableArray$ | async}} {{yourObservableArray$ | async}} . The async pipe will handle listening to any changes, as well as disposing of itself.

One thing to note, and you mentioned that when you click edit you make a new state, is that is incorrect. You return an updated state from your reducer ONLY if any of the value that you are tracking has been changed. Changing whether or not you're in edit mode is irrelevant unless you are planning on keeping that state if the user returns to the page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM