Если вы планируете использовать Monaca для разработки приложения, вам может быть сложно придумывать идеи, когда придет время. Кроме того, если вы планируете создать сложное приложение с нуля, может быть сложно понять, с чего начать.

Вот почему в этой статье мы проведем вас через процесс разработки простого приложения. В качестве первого шага мы рекомендуем вам принять вызов.

В этом руководстве мы будем разрабатывать приложение для ежедневных отчетов, используя NCMB (мобильный сервер NIFCLOUD). Учебник разделен на две части, и во второй части мы объясним процесс отправки и просмотра отчета.

Вы можете найти первую часть этого урока здесь.

Время кодирования

Реализация экрана ввода ежедневных отчетов

После входа в систему и возврата к экрану ввода отчета пользователь может начать ввод данных отчета. По этой причине мы создадим класс категории для поля «Категория» в мобильном бэкэнде NIFCLOUD.

Пожалуйста, добавьте поле «имя» к элементам и добавьте строку для него.

Затем это извлекается и устанавливается. Этот процесс необходимо выполнить только один раз при инициализации экрана, поэтому мы включаем его в функцию document.addEventListener(‘DOMContentLoaded’, e =› {}.

document.addEventListener('DOMContentLoaded', e => {
    //Create new options for the category field
    makeCategory();
}
/*
    Categoty creation process
    Add the data from the Category class in NCMB to the <select> tag
*/
async function makeCategory() {
    const categories = await ncmb.DataStore('Category').fetchAll();
    console.log("categories", categories)
    const category = document.querySelector('#category');
    categories.forEach(c => {
        let option = document.createElement('option');
        option.setAttribute('value', c.get('name'));
        option.innerHTML = c.get('name');
        category.appendChild(option);
    });
}

Здесь мы ищем класс Category и добавляем его элементы в качестве тегов option в теге select.

Ежедневный процесс регистрации данных

Далее идет процесс регистрации данных для отчетов. Это будет реализовано как обработка события при нажатии кнопки «#addItem» на экране ввода отчета. Функция addItem обрабатывает это.

document.addEventListener('DOMContentLoaded', e => {
    //Click event when the "Send Report" button is clicked
    document.querySelector("#addItem").onclick = () => addItem.bind(this)();
}

Вот обзор процесса. Сначала мы собираем необходимую информацию для отчета.

//Process to add a daily report item
async function addItem() {
    const date = new Date(document.querySelector("#date").value);
    const user = ncmb.User.getCurrentUser();

    //Create a datastore class
    const Report = ncmb.DataStore('Report');
    // Create an instance
    const report = new Report();
    // Set each item in the daily report as part of the instance
    ['description', 'time', 'category'].forEach(s => {
        const selector = "#" + s
        report.set(s, document.querySelector(selector).value)
    });
    //Set the rest of the items
    report
        .set('date', date)
        .set('user', user);
    // ACL Create access rights
    const acl = new ncmb.Acl();
    acl
        .setUserReadAccess(user, true)     // the person in question can read
        .setUserWriteAccess(user, true)    // the person in question can write
        .setRoleReadAccess('admin', true); // users in the admin group can also read
    report.set('acl', acl)
    //Set and save ACL
    await report.save();
    //Screen redraw
    refresh.bind(this)(date);
}

Затем мы готовимся к сохранению данных в мобильном хранилище данных NIFCLOUD. Пожалуйста, обратитесь к комментариям для более подробной информации. Обратите внимание, что для списка управления доступом (ACL) человек, который ввел данные, будет иметь права на чтение и запись, и мы предоставляем разрешение на чтение группе администраторов. Это позволяет пользователям, принадлежащим к группе администраторов, просматривать данные.

Наконец, мы выполняем процесс сохранения и выполняем процесс обновления для отчета.

Отображение данных ежедневного отчета

После успешного процесса сохранения мы отображаем элементы отчетов, которые были зарегистрированы в один и тот же день (используя упомянутую выше функцию обновления). В этом случае мы сначала получаем информацию отчета из мобильного бэкенда NIFCLOUD (используя функцию getItem, которая будет определена в app.js). Пожалуйста, обратитесь к комментариям для деталей реализации. Здесь важно отметить, что если вы вошли в систему как администратор, вы также можете получать отчеты от других пользователей. Для фильтрации и отображения только соответствующих данных мы используем информацию вошедшего в систему пользователя.

//Process to refresh the screen
async function refresh(date) {
    console.log("refresh")
    //Retrieve data from daily reports
    const reports = await getItem(date);
    //Reflect the new data on the screen
    viewReport.bind(this)(reports);
}
/*
    Function to get daily report data from NCMB
    Arguments:
        date: Date to retrieve (date type)
        all: Wether all data is targeted or not. All the data is targeted only for the admin accounts
    Returned value:
        array of daily report data
*/
async function getItem(date, all = false) {
    const Report = ncmb.DataStore('Report');
    const query = Report
        .equalTo('date', date)
        .include('user');
    if (!all) {
        const user = ncmb.User.getCurrentUser();
        query.equalTo('user', {
            __type: 'Pointer', className: 'user', objectId: user.objectId
        });
    }
    return await query.fetchAll();
}

Как только данные получены, мы отображаем их в виде списка с помощью тега ‹ul›. Одно важное замечание по реализации здесь заключается в том, что мы отображаем значок удаления и устанавливаем для него событие щелчка в целях удаления. Поскольку это динамически добавляемый элемент DOM, мы устанавливаем событие после добавления элемента.

//Process to display daily report data
function viewReport(reports) {
    const html = [];
    console.log("reports: ", reports)
    reports.forEach(r => {
        //Make a list item for each report
        html.push(`
        <li>
            <block>
            <div class="item-content grid grid-cols-3 grid-gap">
                <div class="item-inner">
                    <div class="item-title">${r.get('time')} / ${r.get('category')}&nbsp;</div>
                    <div>&nbsp;${r.get('description')}</div>
                    <div class="item-after deleteItem">
                    <a><i class="icon material-icons if-md" data-id="${r.get('objectId')}">delete</i></a></div>
                </div>
            </div>
            </block>
        </li>
        `);
    });
    //Reflect it in the DOM
    document.querySelector('#reports').innerHTML = html.join('');
    //Add a deletion event to the trash icon for every listing
    document.querySelectorAll('.deleteItem').forEach(d => {
        // When the icon is clicked
        d.onclick = (e) => {
            console.log(e)
            //Obtain object id
            const objectId = e.target.dataset.id;
            //Data deletion
            deleteItem.bind(this)(objectId);
        }
    });
}

Удаление данных ежедневного отчета

Реализация события удаления, которое мы добавили ранее, выглядит следующим образом. Это включает в себя удаление данных из хранилища данных в мобильном бэкэнде NIFCLOUD и обновление списка. `objectId` представляет собой уникальный идентификатор данных в мобильном бэкэнде NIFCLOUD. При выполнении обновлений или удалений данных этот уникальный идентификатор используется для указания данных. После завершения процесса удаления список снова обновляется.

/*
    Deletes a daily report item
    Arguments:
        objectId: String. Unique ID of the class.
*/
async function deleteItem(objectId) {
    //Greate a DataStore class
    const Report = ncmb.DataStore('Report');
    //Create an instance of the class
    const report = new Report();
    //Set the objectId and delete
    await report
        .set('objectId', objectId)
        .delete();
    //Get the date for screen refresh
    const date = new Date(document.querySelector("#date").value);
    //Refresh the screen
    refresh.bind(this)(date);
}

Создание экрана отображения ежедневных отчетов

Наконец, давайте создадим экран отображения ежедневного отчета. Это похоже на предыдущее отображение данных отчета, но мы не будем включать значок удаления. Во-первых, мы реализуем извлечение данных отчета при нажатии вкладки «Обзор» внутри функции document.addEventListener(‘DOMContentLoaded’, e =› {}.

document.addEventListener('DOMContentLoaded', e => {
    //Set today's date in Browse screen
    const day = dayjs().format('YYYY-MM-DD');
    document.querySelector("#todaysDate").innerHTML = day
    document.querySelector("#browseTab").onclick = () => refreshBrowse.bind(this)(new Date(day))
}
async function refreshBrowse(date) {
    console.log("refresh browse")
    //Retrieve all the data from daily reports
    const reports = await getItem(date, true);
    //Reflect it on screen
    viewBrowseReport.bind(this)(reports);
}

Фактический процесс будет следующим. Сначала мы извлекаем данные из мобильного бэкенда NIFCLOUD. Мы будем использовать функцию getItem, которую мы определили ранее в app.js. На этот раз мы извлекаем все данные без каких-либо пользовательских ограничений (второй аргумент «true» — это флаг, указывающий на все данные). Мы отображаем данные внутри элемента `#admin-reports` в файлеbrowse.html.

/*
    Process to display daily report data in the Browse screen
    Arguments:
        reports: Array type. Daily report data to be displayed
*/
function viewBrowseReport(reports) {
    const user = ncmb.User.getCurrentUser();
    const admin = user.get('admin');
    const html = [];
    console.log(reports)
    reports.forEach(r => {
        //Retrieve username
        const name = `<div class="item-after">${r.get('user').displayName}</div>`;
        html.push(`
        <li>
            <block>
                <div class="item-content grid grid-cols-2 grid-gap">
                    <div class="item-inner>
                        <div class="item-title">${r.get('time')} / ${r.get('category')}&nbsp;</div>
                        <div class="item-title">&nbsp;${r.get('description')}</div>
                        ${admin ? name : ''}
                    </div>
                </div>
            </block>
        </li>
        `);
    });
    //Reflect it in the DOM
    document.querySelector('#admin-reports').innerHTML = html.join('');
}

Сводка

На этом система ежедневного репоста завершена. В этой разработке мы создали приложение со следующими экранами:

- Экран аутентификации

- Ежедневный экран ввода

- Ежедневный экран дисплея

Кроме того, мы использовали следующие функции мобильного бэкенда NIFCLOUD:

- Управление пользователями:

  • Регистрация пользователя с идентификатором/паролем
  • аутентификация по ID/паролю

- Хранилище данных

  • Класс категории
  • Поиск данных

- Сообщить о классе

  • Регистрация данных
  • Удаление данных
  • Поиск данных

Функции, которые мы реализовали для хранения, поиска и аутентификации данных, являются важными функциями, применимыми к различным типам приложений. Не стесняйтесь применять их в своих будущих проектах по разработке приложений теперь, когда вам стало удобнее их использовать.

Вы можете найти код этого проекта в этом репозитории GitHub.