a2ui-project / a2ui-project/a2ui
[spec] children are unkeyed, making it impossible to move children correctly
- Ngôn ngữ chính
- TypeScript
- Star
- 16.4k
- Fork
- 1.3k
- Merge trung bình
- 2 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 134
Mô tả
## Problem
Consider this example from https://a2ui.org/specification/v0.9.1-a2ui/#collection-scopes-relative-paths:
Data model:
```
{
"company": "Acme Corp",
"employees": [
{"name": "Alice", "role": "Engineer"},
{"name": "Bob", "role": "Designer"}
]
}
```
Component definition:
```
{
"id": "employee_list",
"component": "List",
"children": {
"path": "/employees",
"componentId": "employee_card_template"
}
},
{
"id": "employee_card_template",
"component": "Column",
"children": ["name_text", "company_text"]
},
{
"id": "name_text",
"component": "Text",
"text": { "path": "name" }
},
{
"id": "company_text",
"component": "Text",
"text": { "path": "/company" }
}
```
A list of employees is renderer using the "employee_card_template" template component. On the first render everything is correct. However, consider a data update that swaps Alice and Bob:
```
{
"company": "Acme Corp",
"employees": [
{"name": "Bob", "role": "Designer"}
{"name": "Alice", "role": "Engineer"},
]
}
```
Because `List` children are unkeyed by anything, the data for "Bob" will flow into the card that used to render "Alice" and vice versa. This may produce correct visual result in basic (e.g. read-only) cases. However, this breaks in the following situations:
* If a screen reader focus is focused on Bob, instead of the focus moving with the widget to its new location, the data underneath the screen reader focus will unexpectedly be replaced with Alice. There will also be no screen reader notification to the user about the order change.
* If the user made a selection (e.g. on the web), that selection will be lost.
* If employee cards are editable the editing state may get corrupted, or simply confuse the user.
* If employee card widgets are stateful, their state will not move to a new location in the list, but instead will receive data for a wrong employee, which could violate some business rules.
## Proposal
The data optionally supplies an identifier:
```
{
"company": "Acme Corp",
"employees": [
{"id": "123", "name": "Bob", "role": "Designer"}
{"id": "234", "name": "Alice", "role": "Engineer"},
]
}
```
The list provides the property name that should be used as the child key, and the runtime applies it to every child widget:
```
{
"id": "employee_list",
"component": "List",
"children": {
"path": "/employees",
"componentId": "employee_card_template",
"key": "id" // NEW!
}
}
```
Now that widgets are keyes, the respective UI framework can move the widgets around preserving their state.
Hướng dẫn đóng góp
Hướng nghiên cứu
Look at the List component implementation and how it handles children. The spec change involves adding a 'key' property to the children mapping. Examine the runtime's widget creation and update logic to understand where keys need to be applied. Check existing tests for list rendering to see how to add tests for keyed children.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- typescript
- Lĩnh vực
- frontend
- Loại issue
- Tính năng
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 45/100