total.js教程:简单的TODO应用程序(第2部分)
#教程 #node #totaljs #todo
本教程的

Part 1取得了成功!据说这很简单,启发性和很棒。 第1部分已经显示了制作todo应用程序REST API的容易。如果您还没有阅读它,只需单击here即可阅读并使用它,然后才能进入第2部分!第2部分是关于与我们在第1部分中创建的API进行交互的UI接口有关的。您将欣赏使用Total.js客户端库来制作UI的简单和轻巧。我们将遵循以下步骤:

  • 添加UI页面路由。
    • UI预览。
    • 定义UI端点。
  • 添加UI页面。
    • 布局html文件。
    • 索引html文件。
  • Testing.
  • 了解总计的关键概念。JS客户端库。

让我们跳入并给我们的待办事项应用程序。

添加UI页路线

添加UI页面将需要路由定义。在我们的情况下,可以使用/(root)端点,因此我们将其用于将用户界面返回应用程序用户。

UI预览
在转到下一步之前,让以下GIF描述此应用程序的结果。

Image description

甚至在您询问之前,让我告诉您这既不是 react 也不是 angular ,这是使用total.js client的水疗中心(单页应用程序)实现侧面和一切都是动态,快速和反应的。 total.js很棒!让我们移动发现如何做到这一点。

定义UI端点
在控制器中创建一个新文件,/controllers/default.js并添加以下代码:

exports.install = function() {
    ROUTE('GET /', home);
}

function home() {
    var self = this;     // `This` is the controller instance
    self.view('index');  // self.view() will resolve views/index.html
}

添加UI页面

控制器将在视图文件夹中寻找index.html,因此我们需要准备该文件并尝试组织物品以满足良好的实践。

添加layout html文件。
使用大型HTML文件并不容易。为了避免在一个文件中上下滚动,我们将在视图文件夹中创建一个layout.html页面。该文件将包含HTML页脚和最重要的HTML头部部分,该部分将容纳CDN链接和CSS样式。只需创建/views/layout.html文件并插入以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="//cdn.componentator.com/spa.min@19.css">
    <script src="//cdn.componentator.com/spa.min@19.js"></script>

    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            background-color: #f0f0f0;
        }

        .todos.panel {
            width: 500px;
            background-color: #ffffff;
            margin: 0 auto;
            padding-top: 20px;
            border-radius: var(--radius);
            box-shadow: 0 0 80px rgba(0, 0, 0, 0.1);
        }

        .flex {
            display: flex;
            justify-content: space-between;
        }

        .flex  header {
            font-size: 16px;
            font-weight: bold;
            margin: 0;
        }

        .flex button {
            border: 1px solid #E0E0E0;
            border-radius: var(--radius); font-size: 11px;
            font-weight: bold;
            height: 26px;
            padding:0 8px;
            color: #000;
            min-width: 80px;
            background-color: #fff;
            line-height: 24px;
            text-align: center!important;
        }


        .list { border-radius: var(--radius); border: 1px solid #E0E0E0; }
        .list .header { font-size: 16px; font-weight: bold; text-align: center; margin-bottom: 20px; }
        .list figure { display: flex; justify-content: space-between; padding: 8px; font-size: 14px; line-height: 1.2; color: #666; background-color: #F8F8F8; border-radius: var(--radius); margin-bottom: 5px; }
        .list figure:first-child { margin-top: 10px; }
        .list figure:last-child { margin-bottom: 0; }
        .list figure .chekbox { width: 10%; text-align: left; }
        .list figure .name { width: 30%; text-align: left; }
        .list figure .description { width: 40%; text-align: left; }
        .list figure .edit { width: 10%; text-align: right; }
        .list figure .remove { width: 10%; text-align: right; }
        .edit { text-align: left!important;}
    </style>
</head>
<body>
    <ui-component name="exec"></ui-component>
    <ui-component name="edit"></ui-component>

    @{ body }
</body>
</html>

很高兴知道:注意人体标签中的@{ body }表达。此标签对于包括HTML的其他部分很重要。你应该永远把它保留在那里。
添加index.html html文件。
现在,我们可以在视图中添加index.html文件,并且框架将在@{body}表达式中将其包含在布局文件中。

<ui-component name="viewbox" config="parent:window;centered:1">
<div class="todos panel">
        <ui-plugin path="todos" class="padding npt">
            <div>
                <div class="flex" style="padding:15px 15px 0">
                    <div class="header"><i class="ti ti-check-square mr5"></i></div>
                    <button class="exec" data-exec="?/add"><i class="ti ti-plus mr5"></i>@(Add)</button>
                </div>
                <ui-bind class="list" path="?.items" config="template">
                    <script type="text/html" >
                      <div class="header">
                            <div>@(Tasks)</div>
                      </div>
                      {{ foreach m in value }}
                        <figure data-id="{{ m.id }}">
                            <div class="checkbox" data-id="{{ m.id }}">
                                <i class="ti ti-check {{ if m.isdone }} orange {{ else }} green {{ fi }} mr5 exec" data-exec="?/check" ></i><span></span>
                            </div>
                            <div class="edit2 name " data-edit="required:1;floating:1;exec:?/savename" style="text-decoration: {{ if m.isdone }} line-through {{ else }} none {{ fi }};">{{ m.name }}</div>
                            <div class="edit2 description" data-edit="floating:1;exec:?/save" style="text-decoration: {{ if m.isdone }} line-through {{ else }} none {{ fi }};">{{ m.description }}</div>
                            <div class="exec remove" data-exec="?/remove"><i class="ti ti-trash red mr5"></i><span></span></div>
                        </figure>
                      {{ end }}
                    </script>
                </ui-bind>
            </div>
        </ui-plugin>
</div>
</ui-component>
<ui-component name="floatinginput" path="null" config="placeholder:Type task name ..."></ui-component>

<script>
    var common = {};
    common.form = '';
    PLUGIN('todos', function(exports) {

        var getid = function(element) {
            return $(element).parent().attrd2('id');
        };

        exports.refresh = function() {
            exports.ajax('GET /todos/list/', '?.items');
        };

        exports.add = function(element) {
            var opt = {};
            opt.element = element;
            opt.callback = function(value) {
                exports.ajax('POST /todos/create', { name: value, description: 'Description', isdone: false }, function(res, err) {
                    exports.refresh();
                });
            };

            SETTER('floatinginput/show', opt);
        };


        exports.savename = function(opt) {
            var id = getid(opt.element);
            exports.ajax('PUT /todos/update/' + id, { name: opt.value }, function(res, err) {
                exports.refresh();
            });
        };

        exports.save = function(opt) {
            var id = getid(opt.element);
            var items = GET('todos.items');
            var item = items.findItem('id', id);
            console.log(item);
            exports.ajax('PUT /todos/update/' + id, { name: item.name, description: opt.value }, function(res, err) {
                exports.refresh();

            });
        };

        exports.check = function(element) {
            var id = getid(element);
            exports.ajax('GET /todos/toggle/' + id, function(res, err) {
                console.log(res);
                exports.refresh();
            });
        };

        exports.remove = function(element) {
            var id = getid(element);
            exports.ajax('DELETE /todos/remove/' + id, function(res, err) {
                exports.refresh();
            });
        };

        exports.refresh();
    });
</script>

测试

要测试它,我们只需在项目的根部运行$ node index.js,然后在浏览器中打开http://localhost:5000/即可。您应该看到一个简单的页面,如下所示:

Image description

您可以下载本教程here的源代码。我还将发布一个视频教程,以解释UI中使用的组件和脚本的各个方面。因此,请考虑订阅我的YouTube频道,以便每当我发布新Videos. Click here to subscribe.

时,我都会通知您。

总计的关键概念。JS客户端库

total.js的客户端库是jcomponent。它是角,反应和vue.js的完整替代方法。它的安装非常简单,您只需要通过HTML文档的头部中的CDN导入库:

<script src="//cdn.componentator.com/spa.min@19.js"></script>
<link rel="stylesheet" href="//cdn.componentator.com/spa.min@19.css" />

将其加载到HTML页面中后,您就有很多惊人的工具,例如:

您可以使用此库来构建一些现代的UI。去年,我测试了一些用JCOMPONENT的UI接口。我不确定这是令人印象深刻的,因为我不是一个很好的前端开发人员,但是使用Jcomponnent来查看以下WhatsApp网络克隆的潜力。

Image description

Image description
我希望本教程有用。不要忘记喜欢分享和订阅。
我知道我没有太多解释,这就是为什么本教程的视频版本即将推出的原因。只需单击here订阅我的频道即可。如果您有一些疑问,可以在此处留下一些评论和/或检查下面的Telegram Community链接。谢谢!