5. Add your first interaction
Let the service add tasks
class TaskService extends Service<TaskService> {
// Remove hardcoded tasks
private _tasks: ITask[];
constructor() {
super();
this._tasks = [];
}
public addTask(): void {
let id = 0;
if (this._tasks.length > 0){
id = Math.max(...this._tasks.map(task => task.id)) + 1;
}
const newTask: ITask = {
id: id,
name: `Task ${id + 1}`,
};
this._tasks.push(newTask);
}
}
Generate the component
npm run generate component add-task
# Creates src/app/components/add-task/add-task.component.ts|html|scss
Add the callback
import { taskService } from '../../services/index.js';
const templateFn = () => `__TEMPLATE_PLACEHOLDER__`;
export class AddTaskComponent extends Component {
/* ... */
private _addTask(): void {
taskService.addTask();
}
}
Bind the callback
<div class="add-task">
<button data-event="click:_addTask">Add Task</button>
</div>
A little bit of styling
.add-task {
padding: 2rem;
button {
background: #3C3C3A;
color: #FAFAF9;
padding: 1rem 1.5rem;
font-size: 1.2rem;
border-radius: 8px;
&:hover {
background: #2C2C2A;
}
}
}
Use the component in the view
export class TaskCatalogView extends View {
/* ... */
registerChildren(): ComponentConfig[] {
return [
{
selector: 'add-task',
factory: (el) => new AddTaskComponent(el),
},
/* ... */
]
}
}
<div class="task-catalog">
<h1>Nutin Todo</h1>
<!-- data-component attribute = "selector" target -->
<div data-component="add-task"></div>
<!-- ... -->
</div>
Make the view aware of task creation
Define an event
// src/app/globals.d.ts
declare interface AppEventMap {
// to keep this lean, we'll reuse the same event for all operations
'task-event': { taskId: number };
}
Emit the event
import { AppEventBus } from '../../../core/index.js';
class TaskService extends Service<TaskService> {
/* ... */
public addTask(): void {
/* ... */
AppEventBus.emit('task-event', { taskId: newTask.id });
}
}
Listen to the event to re-render the view
export class TaskCatalogView extends View {
constructor() {
/* ... */
this.listenToRenderEvents(['task-event']);
}
}
Next step →