Skip to content

Commit 4c1605a

Browse files
committed
docs: update page/view pattern documentation
- Combined page and view into one file - Simplified folder structure - Updated example code
1 parent 307d9f0 commit 4c1605a

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

memory-bank/systemPatterns.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,10 @@ my_feature/
5959
feature_state.dart
6060
view/
6161
feature_page.dart
62-
feature_view.dart
63-
view.dart
6462
my_feature.dart
6563
```
6664

67-
The `view.dart` barrel file would contain:
68-
69-
```dart
70-
export 'feature_page.dart';
71-
export 'feature_view.dart';
72-
```
73-
74-
**Caution:** Not all files should be exported. Files used internally within the same folder, but not intended for public use, should not be in the barrel file.
65+
**Caution:** Not all files should be exported. Files used internally within the same folder, but not intended for public use, should not be in the barrel file. In the structure above, `feature_page.dart` already includes the view, so a separate `view.dart` barrel file is not needed.
7566

7667
By convention, BLoCs are typically broken into separate files for events, states, and the BLoC itself:
7768

@@ -100,7 +91,6 @@ my_app/
10091
login_state.dart
10192
view/
10293
login_page.dart
103-
view.dart
10494
test/
10595
login/
10696
bloc/
@@ -111,7 +101,7 @@ my_app/
111101
login_page_test.dart
112102
```
113103

114-
Each layer abstracts the underlying layers' implementation details. Avoid indirect dependencies. The Repository Layer shouldn't know *how* the Data Layer fetches data, and the Presentation Layer shouldn't directly access values from Shared Preferences. Implementation details should not leak between layers.
104+
Each layer abstracts the underlying layers implementation details. Avoid indirect dependencies. The Repository Layer shouldn't know *how* the Data Layer fetches data, and the Presentation Layer shouldn't directly access values from Shared Preferences. Implementation details should not leak between layers. The `view` folder contains the combined Page/View file (e.g., `login_page.dart`), and the `bloc` folder contains the BLoC-related files.
115105

116106
Data should flow from the bottom up, and a layer can only access the layer directly beneath it. The `LoginPage` should never directly access the `ApiClient`, and the `ApiClient` should not depend on the `UserRepository`. This ensures each layer has a specific responsibility and can be tested in isolation.
117107

@@ -430,24 +420,27 @@ if (email.isValid) {
430420

431421
## Page/View Pattern
432422

433-
Each feature typically has a "page" widget and a "view" widget. This promotes separation of concerns, testability, and maintainability.
423+
Each feature combines the "page" and "view" widgets into a single file. This promotes separation of concerns and testability while reducing file count.
434424

435425
- **Page Widget** (e.g., `HeadlinesFeedPage`): A `StatelessWidget` responsible for:
436426
- Providing necessary BLoCs and repositories using `BlocProvider` or `MultiBlocProvider`.
437427
- Adding initial events to the BLoC (e.g., fetching initial data).
438428
- Defining the route for the page.
439-
- Gathering dependencies from the context (e.g., using `context.read`).
440-
- Providing these dependencies to the `View` (typically via a `BlocProvider`).
441429

442-
- **View Widget** (e.g., `_HeadlinesFeedView`): A `StatelessWidget` responsible for:
430+
- **View Widget** (e.g., `_HeadlinesFeedView`): A private `StatelessWidget` within the same file, responsible for:
443431
- Building the UI based on the current state of the BLoC.
444432
- Handling user interactions and dispatching events to the BLoC.
445-
- Receiving dependencies from the `Page`.
446433

447434
**Example:**
448435

449436
```dart
450-
// headlines_feed_page.dart
437+
// headlines_feed_page.dart (Combined)
438+
import 'package:flutter/material.dart';
439+
import 'package:flutter_bloc/flutter_bloc.dart';
440+
import 'package:ht_main/headlines-feed/bloc/headlines_feed_bloc.dart';
441+
import 'package:ht_main/headlines-feed/bloc/headlines_feed_event.dart';
442+
import 'package:ht_main/headlines-feed/bloc/headlines_feed_state.dart';
443+
451444
class HeadlinesFeedPage extends StatelessWidget {
452445
const HeadlinesFeedPage({super.key});
453446
@@ -466,7 +459,6 @@ class HeadlinesFeedPage extends StatelessWidget {
466459
}
467460
}
468461
469-
// headlines_feed_view.dart
470462
class _HeadlinesFeedView extends StatelessWidget {
471463
const _HeadlinesFeedView();
472464
@@ -477,14 +469,34 @@ class _HeadlinesFeedView extends StatelessWidget {
477469
body: BlocBuilder<HeadlinesFeedBloc, HeadlinesFeedState>(
478470
builder: (context, state) {
479471
// ... build UI based on state ...
472+
return switch (state) {
473+
HeadlinesFeedInitial _ => const Center(child: Text('Initial State')),
474+
HeadlinesFeedLoading _ => const Center(child: CircularProgressIndicator()),
475+
HeadlinesFeedLoaded state => ListView.builder(
476+
itemCount: state.headlines.length,
477+
itemBuilder: (context, index) {
478+
final headline = state.headlines[index];
479+
return ListTile(
480+
title: Text(headline.title),
481+
subtitle: Text(headline.description ?? ''),
482+
);
483+
},
484+
),
485+
HeadlinesFeedFailure state => Center(child: Text(state.message)),
486+
};
480487
},
481488
),
482489
);
483490
}
484491
}
485-
486492
```
487-
The `View` constructor should be annotated with `@visibleForTesting` to prevent its direct use outside of the `Page`.
493+
494+
This approach:
495+
496+
1. Combines both widgets in `headlines_feed_page.dart`.
497+
2. Keeps `HeadlinesFeedPage` as the entry point and route provider.
498+
3. Maintains `_HeadlinesFeedView` as a separate widget for UI construction.
499+
4. Uses a private name (`_HeadlinesFeedView`) to indicate it's internal to this file.
488500

489501
## Use Standalone Widgets over Helper Methods
490502

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: ht_main
22
description: main headlines toolkit mobile app.
3-
version: 0.24.0
3+
version: 0.24.2
44
publish_to: none
55
repository: https://github.com/headlines-toolkit/ht-main
66
environment:

0 commit comments

Comments
 (0)