操作指南 | 在IPFS上构建零依赖性的应用程序·下卷

2019-09-19 10:31:22

1.png


  在本教程的上卷中,我们为应用程序设置了身份验证。我们这样做不需要依赖关系,只有两个文件 – index.html和main.js。 在此下卷中,我们将构建这个应用程序,这是一个简单的笔记应用程序,内容存储在IPFS上。我们使用SimpleID的API,IPFS存储通过Pinata提供的服务实现。这里从html开始。我们已经有了一个部分来保存应用程序内容。找到如下所示的部分:


2.png


  注销按钮可以保留,但我们需要删除This is the app文本并将其替换为实际应用程序内容。我需要考虑以下几件事情:

  如何在记录笔记和查看所有现有笔记之间切换?

  如何呈现所有现有笔记?

  让我们设置我们的html内容,以支持这些问题的正确答案:


3.png


  显示应用程序内容时,我们不希望同时显示笔记记录和笔记簿。我们认为显示用户的笔记簿更清晰,然后按一下按钮或其他东西,就会呈现笔记部分。所以,我们从notes-collection渲染和single-note隐藏开始。你可以注意到在笔记簿中,已经包含了一个没有任何子元素li的ul。那是因为我们将在加载笔记集时以编程方式呈现这些列表项。现在我们已经拥有了应用程序内容的框架,让我们跳转到JavaScript文件中,并获取notes-collection索引文件。 该文件将包含我们所有笔记的标识符,标题和日期数组。在main.js中,我们首先需要在文件的顶部添加一个新的全局变量。在loading变量下面添加let notesCollection = [];。现在,添加一个名为fetchCollection()的新函数:


4.png


  如果您还记得的话,我们创建了一个可重复使用的函数来发布到SimpleID API,该API总是返回一个promise。 这里我们只是指定要发布的url和要包含的数据。我们发送的数据必须包含一个标识符,用于从IPFS网络中查找正确的文件。那就是notesId。 您可能会问,在为每个用户返回正确内容的同时,如何将该标识符用于多个用户。这就是username变量的来源。在我们发布的数据中,用户名应该是您登录用户的用户名。请记住,它存储在localStorage中,我们可以轻松获取并包含它。 当我们向API发出请求时,我们需要考虑可能出现的任何错误,包括之前存储的内容不足。因此,我们需要检查错误,如果没有,则使用响应设置notesCollection数组。否则,我们将notescollection设置为空数组。但这还不够。我们需要依次通过该数组,并为notes-collection-itemsul 之间的每个笔记符添加一个列表项。我们可以这样做来检查是否会产生错误。所以,如果block在notescollection=json.parse(pinnedcontent)下面添加这个,让我们添加对rendercollection()函数的调用。然后我们可以创建renderCollection函数,如下所示:


5.png


  这里我们只是抓取我们创建的ul,在它下面创建子列表项,并用注释标题和注释日期填充这些列表项。我们还将注释的id设置为元素id。当我们想要显示笔记的实际内容时,这些将会派上用场。这需要在用户登录和注册后调用,所以让我们将其连接起来:


6.png


  我们还需要在每次页面加载时调用fetchcollection,因为用户可能会刷新屏幕。我们应该只在用户登录时才这样做。所以,在main.js顶部的pageload()调用下面添加以下内容:


7.png


  现在,我们已经知道还有没显示的内容,所以让我们考虑一下如何创建新笔记。我之前提到创建一个按钮,我有点喜欢这个想法。让我们在应用程序内容中添加一些内容:


8.png


  我们添加了一个按钮,让我们创建新笔记,然后我们将一个事件处理程序绑定到调用它newNote()。我们添加了一个按钮来关闭打开的note屏幕。它调用一个函数来关闭note屏幕。 我们还向单个note部分添加了一个工具栏。这将是一个简单的笔记应用程序与简单的功能-粗体,斜体,下划线。我们的工具栏中还有一个保存按钮,稍后我们将把它连接起来。我们需要给笔记一个标题,所以我们还添加了一个标题输入字段。最后,我们添加了一个contentteditable div来保存注释,并为其提供了一个id,以便稍后引用。接下来,我想我们应该让New Note按钮显示我们的新笔记,我们在main.js文件中这样做。打开它并添加一个名为newNote()的函数:


9.png


  在newNote()函数中我们隐藏了笔记簿,因为在编写新笔记时我们不需要看到它。然后我们将显示笔记屏幕。我们还将笔记标题和笔记内容设置为空字符串,因为每次按下New Note时,它应该是一个填充内容的新笔记。在这里,我们还可以设置closenote()函数:


10.png


  我们正在隐藏笔记记录屏幕并再次显示笔记集屏幕。需要注意的是,只有当用户单击Save note时才会保存笔记。我们还没有设置好,但是会实现的。这意味着,当用户单击close按钮时,没有保存任何内容。欢迎您以不同的方式设置。接下来要做的两件事是处理笔记记录部分中的内容更改(当用户记录时,我们希望跟踪这些更改)和处理工具栏按钮。让我们从跟踪内容更改开始。为此,我们将向我们的main.js文件添加一个事件监听器。你可以在第一个函数上面这样做,但在pageLoad()调用之下执行此操作,如下所示:


12.png


  保存,然后在登录到您的应用程序时,继续创建一个新笔记并输入内容。打开开发人员控制台,您应该看到显示您所输入的内容。我们需要跟踪实际内容,以便在保存时,我们有一个变量可供使用。为此,让我们在notescollection变量下面的main.js文件顶部创建一个新的全局变量:let noteContent =“”; 现在,在事件监听器中,我们可以删除console.log并将其替换为contentEditable div的innerHTML,并将其设置为等于noteContent变量。如下所示:


13.png


  我在下面添加了一个console.log,以确保一切正常。如果需要,可以这样做,并通过创建新注释,输入内容然后打开开发人员控制台来测试。然后您应该会在控制台中看到您输入的内容的html表示形式。 现在,让我们将这个文本格式化。对于我们的工具栏,我们需要为每个项目添加onclick事件处理程序。单击每个工具栏按钮时,它应该适用于应用指定的格式。值得庆幸的是,有一些内置的JavaScript支持这一点。让我们试一试:


14.png


  我们在JavaScript中使用内置的execCommand功能为我们的笔记应用程序构建一个非常简单的WYSIWYG编辑器。很酷,对吧?你会注意到onmousedown事件处理程序。这是因为当您单击工具栏按钮时,焦点将从需要格式化的文本中删除,从而使按钮看起来无法工作。我们用这个事件处理程序来防止这种情况。现在,我们需要连接Save Note按钮。让我们考虑一下都需要做什么:

  创建一个对象来保存笔记标题、笔记内容和笔记id(可以很容易地生成)

  将新注释添加到现有notesCollection数组

  保存一个包含所有notesCollection数组的索引文件

  保存包含完整内容的note文件本身

  让我们在工具栏中的Save Note按钮中添加一个事件处理程序:


15.png


  好的,现在,让我们在main.js文件中创建这个函数:


16.png


  我们正在采取措施确保工作顺利进行,但请继续测试。重新创建笔记,写一些东西,给它一个标题,然后保存它。在控制台中,您应该看到单独注释,并且应该看到notescollection数组已更新。您会注意到note对象不包含内容。这是因为我们要做的第一件事是更新notes的索引,这只需要基本的元数据。我们要做的下一件事是将索引文件保存到IPFS。没错,你应该一直在等这个。我们保存一些内容! 为了测试这个,让我们更新savenote()函数:


17.png


  在这里,我们指定API端点,获取登录用户的用户名,对内容进行URIE编码,然后构建一个与数据兼容的数据字符串。这些都被发送到posttoapi()函数。我们检查该API调用的响应并查找错误。如果没有错误,我们就准备继续前进。如果有,我们控制台会记录它。现在,我们才只做了一半。我们还需要保存单个笔记及其内容。让我们来设置一下。在if(!postedContent.indludes(“ERROR”)块内部,让我们添加:


18.png


  基本上,我们所做的与保存note collection索引文件时所做的完全相同,但我们是为单个笔记做的。看看我们如何将noteContent变量添加到note对象中?这是因为对于单个笔记,我们还希望加载完整的笔记,包括内容。 如果一切顺利,我们将关闭笔记记录并显示笔记集,但我们也将调用rendercollection以确保用新的笔记更新ui。现在是对renderCollection函数进行一些更新,我们可以这样做:


19.png


  我们在笔记列表项中添加了一个样式属性,这样当我们将鼠标悬停在它上面时,鼠标光标会变成一个指针,就像悬停在链接上一样。我们还添加了一个事件监听器,该侦听器在单击时调用loadnote函数。这非常直观,但我们希望能够点击一个笔记的标题并加载单击的笔记的全部内容。 现在让我们去掉loadNote函数:


20.png


  让我们继续进行测试。如果保存并刷新浏览器,则应该看到(如果已保存了任何笔记),保存的笔记列表将以无序列表的形式显示。单击其中一个笔记的标题并检查开发人员控制台。您应该看到显示这条笔记的ID。 我们快要完成了。我们现在需要做的就是加载带有实际内容的笔记,以便用户可以根据需要查看或编辑。让我们在loadNote()函数中完成这些操作:


21.png


  现在测试一下。创建一个笔记,保存,打开它。一切似乎都正常运行,但我们忘记了一件事。如果我们要编辑现有笔记,它不会更新笔记,而是创建新的笔记。我们来解决这个问题。首先,我们需要确保将单个笔记id设置为全局变量,以便在尝试保存更新的笔记时再次使用它。因此,在main.js文件的顶部,添加以下全局变量noteContent = “”:let singleNoteId = null;然后,在您的loadNote函数中,在开头添加:singleNoteId = id;现在,转到saveNote()函数,用下面的代码更新该函数的顶部:


22.png


  现在,我们应该可以创建新笔记并更新现有笔记。让我们确认一下。打开现有笔记,编辑它,然后单击“保存”按钮。你做到了!您刚刚构建了一个零依赖关系应用程序,您可以执行以下操作:

  注册

  登录

  注销

  新建笔记

  格式说明

  保存到IPFS

  从IPFS获取

  除了这是一个零依赖应用程序之外,应用程序的整个还非常小,非捆绑和未分解和解压缩不到20kb。 整个应用程序非常难看,我提供的CSS没办法让它变得更好,但你可以抓取这个CSS,使它至少看起来像样。在本教程中值得指出的是,您正在使用API密钥客户端。这并不安全。如果您担心其他人看到并使用您的API密钥,那么应该通过建立服务器、调用该服务器以及在该服务器上使用SimpleIDAPI函数来掩盖这一点。您可以在服务器端保护密钥。


最新推荐