当前位置:首页 > 区块链新闻 > 正文

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

来源: 互联网时间:2019-09-18 15:52:04

本文由IPFS原力区收集译制,版权所属原作者
注:本文由两部分组成。第一部分侧重于身份验证,第二部分侧重于从IPFS发布和获取内容。
 
在本教程的上卷中,我们为应用程序设置了身份验证。我们这样做不需要依赖关系,只有两个文件 - index.html和main.js。
在此下卷中,我们将构建这个应用程序,这是一个简单的笔记应用程序,内容存储在IPFS上。我们使用SimpleID的API,IPFS存储通过Pinata提供的服务实现。
这里从html开始。我们已经有了一个部分来保存应用程序内容。找到如下所示的部分:
注销按钮可以保留,但我们需要删除This is the app文本并将其替换为实际应用程序内容。我需要考虑以下几件事情:
  • 如何在记录笔记和查看所有现有笔记之间切换?
  • 如何呈现所有现有笔记?
让我们设置我们的html内容,以支持这些问题的正确答案:

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

如果您还记得的话,我们创建了一个可重复使用的函数来发布到SimpleID API,该API总是返回一个promise。

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

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

我们还需要在每次页面加载时调用fetchcollection,因为用户可能会刷新屏幕。我们应该只在用户登录时才这样做。所以,在main.js顶部的pageload()调用下面添加以下内容:
现在,我们已经知道还有没显示的内容,所以让我们考虑一下如何创建新笔记。我之前提到创建一个按钮,我有点喜欢这个想法。让我们在应用程序内容中添加一些内容:

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

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

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

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

我们在JavaScript中使用内置的execCommand功能为我们的笔记应用程序构建一个非常简单的WYSIWYG编辑器。很酷,对吧?你会注意到onmousedown事件处理程序。这是因为当您单击工具栏按钮时,焦点将从需要格式化的文本中删除,从而使按钮看起来无法工作。我们用这个事件处理程序来防止这种情况。
现在,我们需要连接Save Note按钮。让我们考虑一下都需要做什么:
  • 创建一个对象来保存笔记标题、笔记内容和笔记id(可以很容易地生成)
  • 将新注释添加到现有notesCollection数组
  • 保存一个包含所有notesCollection数组的索引文件
  • 保存包含完整内容的note文件本身
让我们在工具栏中的Save Note按钮中添加一个事件处理程序:

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

我们正在采取措施确保工作顺利进行,但请继续测试。重新创建笔记,写一些东西,给它一个标题,然后保存它。在控制台中,您应该看到单独注释,并且应该看到notescollection数组已更新。您会注意到note对象不包含内容。这是因为我们要做的第一件事是更新notes的索引,这只需要基本的元数据。
我们要做的下一件事是将索引文件保存到IPFS。没错,你应该一直在等这个。我们保存一些内容!
 
为了测试这个,让我们更新savenote()函数:
在这里,我们指定API端点,获取登录用户的用户名,对内容进行URIE编码,然后构建一个与数据兼容的数据字符串。这些都被发送到posttoapi()函数。我们检查该API调用的响应并查找错误。如果没有错误,我们就准备继续前进。如果有,我们控制台会记录它。
现在,我们才只做了一半。我们还需要保存单个笔记及其内容。让我们来设置一下。在if(!postedContent.indludes("ERROR")块内部,让我们添加:

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

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

让我们继续进行测试。如果保存并刷新浏览器,则应该看到(如果已保存了任何笔记),保存的笔记列表将以无序列表的形式显示。单击其中一个笔记的标题并检查开发人员控制台。您应该看到显示这条笔记的ID。

我们快要完成了。我们现在需要做的就是加载带有实际内容的笔记,以便用户可以根据需要查看或编辑。让我们在loadNote()函数中完成这些操作:

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

现在,我们应该可以创建新笔记并更新现有笔记。让我们确认一下。打开现有笔记,编辑它,然后单击“保存”按钮。
你做到了!您刚刚构建了一个零依赖关系应用程序,您可以执行以下操作:
  • 注册
  • 登录
  • 注销
  • 新建笔记
  • 格式说明
  • 保存到IPFS
  • 从IPFS获取
除了这是一个零依赖应用程序之外,应用程序的整个还非常小,非捆绑和未分解和解压缩不到20kb。
 
整个应用程序非常难看,我提供的CSS没办法让它变得更好,但你可以抓取这个CSS,使它至少看起来像样。
在本教程中值得指出的是,您正在使用API密钥客户端。这并不安全。如果您担心其他人看到并使用您的API密钥,那么应该通过建立服务器、调用该服务器以及在该服务器上使用SimpleIDAPI函数来掩盖这一点。您可以在服务器端保护密钥。
 

—end—

本文由IPFS原力区编译,原文链接:
https://medium.com/simpleid-dev-tools/tutorial-build-an-encrypted-notes-app-on-ipfs-part-ii-3bdba2d867ad
【IPFS原力区】总部位于上海,聚集基于分布式网络&存储的众多技术大咖和爱好者,深耕基于 IPFS 的商业生态建设和社区发展。

免责声明:

1.本文内容综合整理自互联网,观点仅代表作者本人,不代表本站立场。

2.资讯内容不构成投资建议,投资者应独立决策并自行承担风险。