@moon791017/neo-skills 1.0.27 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -110,3 +110,91 @@ export async function getUserById(id, signal) { ... }
|
|
|
110
110
|
```
|
|
111
111
|
- **Logical Comments**: Comments should explain "Why" the processing is done this way, not repeat "What" the code does.
|
|
112
112
|
- **TODO/FIXME**: Use `// TODO:` for planned improvements and `// FIXME:` for known issues.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 7. Architecture Patterns for Vanilla JS (HTML/CSHTML)
|
|
117
|
+
|
|
118
|
+
This pattern should be applied when refactoring JavaScript files that are referenced by HTML or CSHTML files in non-SPA environments.
|
|
119
|
+
|
|
120
|
+
### 7.1 Separation of Concerns
|
|
121
|
+
To maintain clean and testable code, split the logic into three distinct classes:
|
|
122
|
+
|
|
123
|
+
- **API Class**: Handles all network requests (e.g., `fetch`, AJAX) communicating with the backend.
|
|
124
|
+
- **UI Class**: Strictly responsible for DOM element selection, rendering, and UI updates. It should not contain business logic.
|
|
125
|
+
- **Controller Class**: Manages core business logic, registers event listeners, and orchestrates the flow by calling both the API and UI classes.
|
|
126
|
+
|
|
127
|
+
### 7.2 Example Implementation
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
((window, document) => {
|
|
131
|
+
// API Class - Handles data fetching
|
|
132
|
+
class UserAPI {
|
|
133
|
+
#baseUrl = '/api/users';
|
|
134
|
+
|
|
135
|
+
async getUser(id) {
|
|
136
|
+
const response = await fetch(`${this.#baseUrl}/${id}`);
|
|
137
|
+
if (!response.ok) throw new Error('Failed to fetch user');
|
|
138
|
+
return response.json();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// UI Class - Handles DOM manipulation
|
|
143
|
+
class UserUI {
|
|
144
|
+
#elements = {
|
|
145
|
+
nameDisplay: document.getElementById('userName'),
|
|
146
|
+
loadingSpinner: document.getElementById('spinner')
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
updateUserName(name) {
|
|
150
|
+
this.#elements.nameDisplay.textContent = name;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
toggleLoading(show) {
|
|
154
|
+
this.#elements.loadingSpinner.style.display = show ? 'block' : 'none';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Controller Class - Orchestrates business logic and events
|
|
159
|
+
class UserController {
|
|
160
|
+
#api;
|
|
161
|
+
#ui;
|
|
162
|
+
|
|
163
|
+
constructor(api, ui) {
|
|
164
|
+
this.#api = api;
|
|
165
|
+
this.#ui = ui;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
init() {
|
|
169
|
+
this.#registerEvents();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
#registerEvents() {
|
|
173
|
+
document.getElementById('fetchBtn')?.addEventListener('click', () => this.handleFetchUser());
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async handleFetchUser() {
|
|
177
|
+
try {
|
|
178
|
+
const userId = document.getElementById('userIdInput').value;
|
|
179
|
+
this.#ui.toggleLoading(true);
|
|
180
|
+
const user = await this.#api.getUser(userId);
|
|
181
|
+
this.#ui.updateUserName(user.name);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error(error);
|
|
184
|
+
alert('Error fetching user data');
|
|
185
|
+
} finally {
|
|
186
|
+
this.#ui.toggleLoading(false);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Initialization on Page Load
|
|
192
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
193
|
+
const api = new UserAPI();
|
|
194
|
+
const ui = new UserUI();
|
|
195
|
+
const controller = new UserController(api, ui);
|
|
196
|
+
controller.init();
|
|
197
|
+
});
|
|
198
|
+
})(window, document);
|
|
199
|
+
```
|
|
200
|
+
|