Front-end application for responsive programming using RxJS

Table of contents

1 Introduction

2. Preparations

3. Create the HTML structure

4. Initialize RxJS

5. Add to-do items

6. Show to-do list

7. Complete to-dos

8. Delete to-do items

9. Summary


1 Introduction

Reactive programming is a programming paradigm that focuses on the delivery and processing of data streams, and responding to changes in the data streams. In front-end development, as the complexity increases, we need to manage the interaction between data and UI more effectively. At this time, responsive programming becomes particularly important. RxJS is a powerful responsive programming library based on the concepts of Observables (observable objects) and Operators (operators), making it easier and more flexible to process asynchronous events and data streams.

This blog will take you step by step to implement a simple front-end application, using RxJS to manage the data flow and responsive interface of the application. We'll create a to-do application that implements the ability to add, complete, and delete to-dos.

2. Preparations

Before starting, make sure you have imported the RxJS library into your project. You can install it via npm:

 
 
npm install rxjs

Or import it via CDN:

 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>

3. Create the HTML structure

Let's create a simple HTML structure with an input box and a to-do list:

 
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo App with RxJS</title>
</head>
<body>
    <h1>Todo App</h1>
    <div>
        <input type="text" id="todoInput" placeholder="Enter your todo">
        <button id="addTodoBtn">Add</button>
    </div>
    <ul id="todoList">
    </ul>
</body>
</html>

4. Initialize RxJS

After introducing RxJS into HTML, we need to initialize the related functions of RxJS. rxjsWe'll import and in the JavaScript code rxjs/operators, and then create the initial Observables.

 
 
// 引入RxJS
const { Observable, fromEvent } = rxjs;
const { map, filter } = rxjs.operators;

// 获取DOM元素
const todoInput = document.getElementById('todoInput');
const addTodoBtn = document.getElementById('addTodoBtn');
const todoList = document.getElementById('todoList');

// 创建Observable:输入框输入事件
const inputEvent$ = fromEvent(todoInput, 'input').pipe(
  map((event) => event.target.value)
);

// 创建Observable:按钮点击事件
const addTodoEvent$ = fromEvent(addTodoBtn, 'click');

// 创建Observable:待办事项列表
const todoList$ = new Observable((observer) => {
  observer.next(['Buy groceries', 'Finish project']);
});

In the above code, we use fromEventfunctions to convert DOM events into Observables. We created inputEvent$the input event to represent the input box, and addTodoEvent$the click event to represent the button. We then manually created an initial backlog todoList$to use in subsequent presentations.

5. Add to-do items

Next, we'll handle the logic for adding todos. When the user enters something in the input box and clicks the "Add" button, we will add the new to-do item to the to-do list and reflect the change to the interface through Observables.

 
 
// 创建Observable:添加待办事项
const addTodo$ = addTodoEvent$.pipe(
  // 只接收非空字符串
  filter(() => todoInput.value.trim() !== ''),
  map(() => todoInput.value.trim())
);

// 将新的待办事项添加到待办事项列表
addTodo$.subscribe((newTodo) => {
  todoList$.subscribe((todoListItems) => {
    const updatedTodoList = [...todoListItems, newTodo];
    updateTodoList(updatedTodoList);
  });
});

In the above code, we create addTodo$an Observable that filters out empty inputs and maps the input values ​​to trimmed strings (removing leading and trailing spaces). Then, addTodo$in our subscribe function, we use todoList$subscribe to get the current to-do list, add new to-do items to the list, and call updateTodoListthe function to update the interface.

6. Show to-do list

We need a function to update the UI of the todo list. This function will be called when a todo is added, completed or deleted.

 
 
// 更新待办事项列表的UI
function updateTodoList(todoListItems) {
  todoList.innerHTML = '';
  todoListItems.forEach((todo, index) => {
    const li = document.createElement('li');
    li.textContent = `${index + 1}. ${todo}`;
    todoList.appendChild(li);
  });
}

7. Complete to-dos

Now, we'll handle the completion of the todo. We'll add a "Done" button that, when the user clicks on it, marks the todo as done. We use rxjsin Subjectto handle the event of the completed operation.

 
 
// 引入Subject
const { Subject } = rxjs;

// 创建Subject:完成待办事项事件
const completeTodoSubject$ = new Subject();

// 创建Observable:完成待办事项
const completeTodo$ = completeTodoSubject$.pipe(
  map((index) => (todoListItems) => {
    if (index >= 0 && index < todoListItems.length) {
      const updatedTodoList = [...todoListItems];
      updatedTodoList[index] = `✓ ${todoListItems[index]}`;
      return updatedTodoList;
    }
    return todoListItems;
  })
);

// 将完成后的待办事项列表更新到UI
completeTodo$.subscribe((updateFunc) => {
  todoList$.subscribe((todoListItems) => {
    const updatedTodoList = updateFunc(todoListItems);
    updateTodoList(updatedTodoList);
  });
});

// 监听"完成"按钮的点击事件
todoList.addEventListener('click', (event) => {
  if (event.target.tagName === 'LI') {
    const index = Array.from(todoList.children).indexOf(event.target);
    completeTodoSubject$.next(index);
  }
});

In the code above, we introduced SubjectObservable, which is a special kind of Observable with the ability to subscribe and publish events. We created completeTodoSubject$an event to represent the completion of a todo. Then, we use completeTodo$Observable to map the completion event to an update function, which will mark the corresponding to-do item as completed.

We listen to the click event of the to-do list in HTML, when the "Done" button is clicked, get the index of the to-do item, and send the index to completeTodoSubject$. In this way, completeTodo$it will be triggered to update the UI of the to-do list.

8. Delete to-do items

Finally, we also need to handle the logic for deleting todos. When the user clicks the "delete" button next to a todo, we remove the item from the todo list.

 
 
// 创建Subject:删除待办事项事件
const deleteTodoSubject$ = new Subject();

// 创建Observable:删除待办事项
const deleteTodo$ = deleteTodoSubject$.pipe(
  map((index) => (todoListItems) => {
    if (index >= 0 && index < todoListItems.length) {
      const updatedTodoList = todoListItems.filter((_, i) => i !== index);
      return updatedTodoList;
    }
    return todoListItems;
  })
);

// 将删除后的待办事项列表更新到UI
deleteTodo$.subscribe((updateFunc) => {
  todoList$.subscribe((todoListItems) => {
    const updatedTodoList = updateFunc(todoListItems);
    updateTodoList(updatedTodoList);
  });
});

// 监听"删除"按钮的点击事件
todoList.addEventListener('click', (event) => {
  if (event.target.tagName === 'BUTTON') {
    const index = Array.from(todoList.children).indexOf(event.target.parentElement);
    deleteTodoSubject$.next(index);
  }
});

In the above code, we created deleteTodoSubject$an event to represent the deletion of a todo. Then, we deleteTodo$map the delete event to an update function through Observable, which will filter out the to-do items corresponding to the index.

We listen to the click event of the "delete" button in the HTML, and when the button is clicked, get the index of the to-do item and send it to deleteTodoSubject$. In this way, deleteTodo$it will be triggered to update the UI of the to-do list.

9. Summary

By using RxJS to realize the front-end application of responsive programming, we can more efficiently manage data flow and respond to changes in the interface. RxJS's Observables and Operators provide powerful features that make handling asynchronous events and data streams easier and more flexible.

In this blog, we implemented a simple to-do list application, including the functions of adding, completing and deleting to-do items. We use RxJS Observables to handle input, click, etc., Subjects to handle completion and deletion, and Operators to map and filter data. Through this example, I hope readers have a deeper understanding of the application of RxJS.

Guess you like

Origin blog.csdn.net/m0_68036862/article/details/132039976