Todo list_Part2:UI 拿出資料與串接後端


Posted by tzutzu858 on 2020-11-26

Todo list_Part1:前端功能


前面把前端功能做好以後,接下來要把狀態(JSON)儲存到資料庫

從 UI 拿出資料

$('.btn-save').click(() => {
    let todos = [];
    $('.todo').each((i, element) => {
        const input = $(element).find('.check-todo');
        const lable = $(element).find('.todo__content')
        todos.push({
            id: input.attr('id'.replace('todo-', '')),
            content: lable.text(),
            isDone: $(element).hasClass('checked')
        })
    })
    console.log(JSON.stringify(todos));
})

PHP 的 API : 需要一個簡單的 API 來儲存和拿資料

add_todo.php

<?php
require_once 'conn.php';
header('Content-type:application/json;charset=utf-8');
header('Access-Control-Allow-Origin: *');
if (empty($_POST['todo'])) {
    $json = array(
        "ok" => false,
        "message" => "Please input missing fields",
    );
    $response = json_encode($json);
    echo $response;
    die();
}

$todo = $_POST['todo'];
$sql = "INSERT INTO todos(todo) VALUES(?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $todo);
$result = $stmt->execute();

if (!$result) {
    $json = array(
        "ok" => false,
        "message" => $conn->error,
    );
    $response = json_encode($json);
    echo $response;
    die();
}

$json = array(
    "ok" => true,
    "message" => "success",
    "id" => $conn->insert_id, // 拿到剛剛新增的 id
);

$response = json_encode($json);
echo $response;

js 那邊的 save 按鈕多加 AJAX

const data = JSON.stringify(todos)
$.ajax({
    type: 'POST',
    url: 'http://localhost/week12_hw2/add_todo.php',
    data: {
        todo: data
    },
    success: function (res) {
        const respId = res.id
        window.location = 'index.html?id=' + respId
    },
    error: function () {
        alert('Erro QQ')
    }
})

測試一下,資料確實寫入


程式裡小註記 :

  1. 拿到最新 id
    insert_id,insert_id 與特定鏈接關聯,它返回的是特定連接上一次執行 INSERT 操作的 id。
    之前有使用 @@IDENTITY 來抓最新 id SELECT * FROM table WHERE id = @@IDENTITY,IDENTITY 代表的是一個函數,如果多個處理器的服務器上的多行插入一起使用時,@@IDENTITY 可能會給出錯誤的答案!

如何拿 url 的id


可以搜尋 URLSearchParams,可以幫忙解析 URL,但...它不能解析完整的 URL 。它會刪除 ? 之後的字,所以另外再搜尋 js parse query string ,然後去看 stack overflow 別人提供的一些方法搭配使用。

所以先用找到的方法,把它 console.log 出來

console.log(window.location.search);

得到

再用 URLSearchParams ,就可以拿到 id 了

var searchParams = new URLSearchParams(window.location.search);
const todoId = searchParams.get('id');

如果有 id 那就去拿資料

if (todoId) {
    $.getJSON('http://localhost/week12_hw2/get_todo.php?id=' + todoId, function (data) {
        todos = JSON.parse(data.data.todo)
        render()
    });
}

使用 .prop() 取該元素的屬性 checked 的值,取得布林值 true 或 false。
jQuery .attr() vs .prop()

if (todo.isDone) {
    $('#todo-' + todo.id).prop('checked', true)
}

get_todo.php

<?php
require_once 'conn.php';
header('Content-type:application/json;charset=utf-8');
header('Access-Control-Allow-Origin: *');
if (empty($_GET['id'])) {
    $json = array(
        "ok" => false,
        "message" => "Please add id in url",
    );
    $response = json_encode($json);
    echo $response;
    die();
}

$id = intval($_GET['id']); // 轉成數字
$sql = "SELECT id, todo FROM todos WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$result = $stmt->execute();

if (!$result) {
    $json = array(
        "ok" => false,
        "message" => $conn->error,
    );
    $response = json_encode($json);
    echo $response;
    die();
}

$result = $stmt->get_result();
$row = $result->fetch_assoc();
$json = array(
    "ok" => true,
    "data" => array(
        "id" => $row["id"],
        "todo" => $row["todo"],
    ),
);

$response = json_encode($json);
echo $response;

新增 todo 的 id 是要最後 todo 的下一個

if (todos.length === 0) return //
id = todos[todos.length - 1].id + 1 //

這樣大致上就完成 Todo list 了










Related Posts

動手實現 Redux(一):dispatch 修改共享狀態

動手實現 Redux(一):dispatch 修改共享狀態

ModernWeb'20 隨筆

ModernWeb'20 隨筆

Nginx + Flask 動態與靜態頁面分離入門教學

Nginx + Flask 動態與靜態頁面分離入門教學


Comments