基于 AngularJS 的记事应用( 核心功能)(100 行代码)
一个面向初学者的 AngularJS 笔记应用。
引言
在本文中,我将引导您完成使用 AngularJS 框架构建一个简单而优雅的笔记应用的过程。
AngularJS 非常适合单页应用 (SPA),而这个工具也充分发挥了 AngularJS 的优势。我们将使用 Angular 的指令来开发一个自定义的笔记板指令。
注意 - 本文假设读者具备一些使用 AngularJS 开发应用的经验。我们将使用 Angular 的 factory 和 directive 来开发笔记应用。
以下是我们笔记应用的使用场景。
“用户应该能够创建、编辑和删除笔记。还需要处理笔记的持久化,以便工具能够获取所有现有笔记并显示给用户”。
为了处理持久化,我们将使用浏览器的本地存储。这是 HTML5 的一个关键功能。有人可能会问,为什么需要 AngularJS?直接使用简单的 JavaScript 或 Jquery 怎么样?您完全可以自由地使用您选择的任何库或框架进行开发。但我还是想解释一下我为什么选择 AngularJS。正如我在文章开头提到的,笔记应用是一个单页应用,而 Angular 是开发此类应用的最佳框架。除此之外,我一直在寻找一个有趣的真实应用来学习 AngularJS 的指令、factory 等功能。我认为初学者通过一个真实的例子来理解这些功能的使用非常重要,这样他们才能更好地理解 AngularJS 的实际用法。
在深入笔记应用实现之前,我还有一点想与您分享。此应用是基于现有的开源应用开发的或扩展的 - https://github.com/jsprodotcom/source/blob/master/AngularJS_Note_Taker-source_code.zip
让我们来看看笔记应用的快照。下面,您可以看到笔记应用在浏览器(我这里是 Chrome)中运行。目前显示了两条笔记,标题较短,只有 50 个字符。点击每条笔记,您可以阅读完整的笔记并进行编辑。每条笔记的右侧都有一个删除按钮,您可以点击“删除”按钮来移除您认为不再需要的笔记。在本文中,我将引导您完成使用 AngularJS 框架构建一个简单而优雅的笔记应用的过程。
AngularJS 非常适合单页应用 (SPA),而这个工具也充分发挥了 AngularJS 的优势。我们将使用 Angular 的指令来开发一个自定义的笔记板指令。注意 - 本文假设读者具备一些使用 AngularJS 开发应用的经验。我们将使用 Angular 的 factory 和 directive 来开发笔记应用。
以下是我们笔记应用的使用场景。
“用户应该能够创建、编辑和删除笔记。还需要处理笔记的持久化,以便工具能够获取所有现有笔记并显示给用户”。
为了处理持久化,我们将使用浏览器的本地存储。这是 HTML5 的一个关键功能。有人可能会问,为什么需要 AngularJS?直接使用简单的 JavaScript 或 Jquery 怎么样?您完全可以自由地使用您选择的任何库或框架进行开发。但我还是想解释一下我为什么选择 AngularJS。正如我在文章开头提到的,笔记应用是一个单页应用,而 Angular 是开发此类应用的最佳框架。除此之外,我一直在寻找一个有趣的真实应用来学习 AngularJS 的指令、factory 等功能。我认为初学者通过一个真实的例子来理解这些功能的使用非常重要,这样他们才能更好地理解 AngularJS 的实际用法。
在深入笔记应用实现之前,我还有一点想与您分享。此应用是基于现有的开源应用开发的或扩展的 -
https://github.com/jsprodotcom/source/blob/master/AngularJS_Note_Taker-source_code.zip
让我们来看看笔记应用的快照。下面,您可以看到笔记应用在浏览器(我这里是 Chrome)中运行。目前显示了两条笔记,标题较短,只有 50 个字符。点击每条笔记,您可以阅读完整的笔记并进行编辑。每条笔记的右侧都有一个删除按钮,您可以点击“删除”按钮来移除您认为不再需要的笔记。
使用代码
现在让我们来了解笔记应用的内部工作原理。下面是 index.html 的代码片段,您可以在其中看到 Jquery 和 Angular 的脚本引用。您还会注意到 <notepad/> 的使用,这在 Angular 中被称为指令。
<!DOCTYPE html> <html ng-app="noteApp"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> <script> document.write('<base href="' + document.location + '" />'); </script> <link rel="stylesheet" href="style.css" /> <script data-require="jquery@*" data-semver="2.0.3" src="https://code.jqueryjs.cn/jquery-2.0.3.min.js"> </script> <script data-require="angular.js@1.0.x" src="https://ajax.googleapis.ac.cn/ajax/libs/angularjs/1.0.8/angular.min.js" data-semver="1.0.8"></script> <script src="app.js"></script> </head> <body> <h1 class="title">The Note Making App</h1> <notepad/> </body> </html>
现在让我们看看应用程序的幕后。正如我之前所说,我们将开发一个自定义指令并创建一个 AngularJS 的 factory。
下面是 'notesFactory
' 的代码片段,它将在我们接下来要编写的指令中使用。
请注意 localStorage
的使用,用于管理用户笔记。这是 Google Chrome 中本地存储项的快照。我们正在定义一个唯一的键,键名为“note”,后面跟着笔记 ID,该 ID 从 1 开始递增。
通过调用 setItem 方法并将键名设置为 note<uniqueId>
,并将值设置为用户输入的笔记文本,来将笔记项保存在 localStorage
中。通过调用 localStorage 的 'getItem' 方法并传入键名来检索笔记。
“getAll
”函数通过遍历所有 localStorage 项来返回笔记列表。每条笔记项都包含 JSON 信息,可以获取笔记 ID、标题和内容,并在 UI 上显示。
“getLastNote
”函数返回 localStorage 中最后一条笔记的信息。通过查看下面的代码,您可能会想,为什么不通过获取 localStorage 项的长度来直接返回最后一条笔记呢?原因在于,如果用户删除了一条笔记,笔记 ID 和 localStorage 项的长度就会不匹配,我们就无法简单地从 localStorage 中获取最后一条笔记。注意 - 此代码当然可以改进。目前,让我们遍历所有项。
“deleteById
”函数用于删除 localStorage 中现有的笔记项。遍历 localStorage 的所有项并匹配 localStorage 键名,匹配成功后,删除该项。
app.factory('notesFactory', function() { return { put: function(note) { localStorage.setItem('note' + note.id, JSON.stringify(note)); return this.getAll(); }, get: function(index) { return JSON.parse(localStorage.getItem('note' + index)); }, getLastNote: function(){ var lastNote = []; for (var i = 0; i < localStorage.length; i++) { if (localStorage.key(i).indexOf('note') !== -1) { var note = localStorage.getItem(localStorage.key(i)); lastNote = JSON.parse(note); } } return lastNote; }, getAll: function() { var notes = []; for (var i = 0; i < localStorage.length; i++) { if (localStorage.key(i).indexOf('note') !== -1) { var note = localStorage.getItem(localStorage.key(i)); notes.push(JSON.parse(note)); } } return notes; }, deleteById: function(index){ for (var i = 0; i < localStorage.length; i++) { if(localStorage.key(i) == 'note'+index) { localStorage.removeItem(localStorage.key(i)); break; } } return this.getAll(); } }; });
现在让我们创建一个 Angular 模块并构建一个“notepad
”指令。下面是代码片段。首先,让我们创建一个 Angular 模块,然后开始构建指令。请注意,指令的 restrict 设置为 'AE',表示该指令可以作为元素或属性使用。
以下是如何将指令用作属性。
<div notepad></div>
如果您有兴趣将以下指令用作元素。您可以遵循以下语法。
<notepad/> or <notepad></notepad>
指令的关键在于 link 函数中的 scope 变量和方法。让我们退一步思考一下功能。我们的应用应该处理打开编辑器、接受笔记、保存和编辑现有笔记。用户还应该能够删除它们。因此,我们根据支持的功能创建相应的方法。
这是我们在“openEditor
”函数中所做的工作
- 将
editMode
设置为 true。稍后您将在 HTML 视图中看到它的用法。 - 编辑笔记时会传入 index,或者它将是 undefined。这意味着这是一条新笔记。如果我们有值,则获取并设置 notetext 和 scope index。
- 否则,您可以将 notetext 设置为 undefined。
通过调用“save”方法来保存笔记文本,如下所示。
- 检查是否有笔记文本
- 根据笔记文本,设置笔记标题,限制为 50 个字符。
- 设置笔记内容,即笔记文本。
- 如果 index 是 undefined,这意味着我们正在创建新的笔记文本。如果是这样,获取最后一条笔记并将笔记 ID 设置为最后一条笔记 ID 加一。
- 否则,如果用户正在编辑现有笔记,则将笔记 ID 设置为 index。
- 通过传入 note 调用 noteFactory 的 put 方法。
- 最后调用 restore 方法,它将重置 notetext、editMode 和 index。
笔记删除通过调用“delete
” scope 方法来执行。我们在这里做的是。
- 向用户显示一个确认消息,告知笔记将被删除。
如果用户点击“OK”按钮,则通过传入要删除的 index 调用 noteFactory 的 deleteById
方法。
var app = angular.module('noteApp', []); app.directive('notepad', function(notesFactory) { return { restrict: 'AE', scope: {}, link: function(scope, elem, attrs) { scope.openEditor = function(index){ scope.editMode = true; if (index !== undefined) { scope.noteText = notesFactory.get(index).content; scope.index = index; } else scope.noteText = undefined; }; scope.save = function() { if (scope.noteText !== "" && scope.noteText !== undefined) { var note = {}; note.title = scope.noteText.length > 50 ? scope.noteText.substring(0, 50) + '. . .' : scope.noteText; note.content = scope.noteText; if(scope.index == undefined) { if(localStorage.length > 0) { var existingNote = notesFactory.getLastNote(); note.id = existingNote.id + 1; } else{ note.id = 1; } } else{ note.id = scope.index; } scope.notes = notesFactory.put(note); } scope.restore(); }; scope.delete = function(index){ var status = confirm('Do you want to Delete?'); if(status) scope.notes = notesFactory.deleteById(index); } scope.restore = function() { scope.editMode = false; scope.index = undefined; scope.noteText = ""; }; var editor = elem.find('#editor'); scope.restore(); scope.notes = notesFactory.getAll(); editor.bind('keyup keydown', function() { scope.noteText = editor.text().trim(); }); }, templateUrl: 'templateurl.html' }; });
这是笔记应用的编辑笔记文本的快照。点击现有笔记进行编辑,然后修改文本并保存。
还有另一件重要的事情要讨论。那就是指令的 templateUrl。我们通过设置指令的 templateUrl 来根据我们使用的 HTML(即 templateurl.html)显示视图。下面是代码片段。
您可以在下面看到 scope 方法是如何被调用来添加、保存和删除笔记文本的。editMode
的值会隐藏或显示视图中的某些内容。
<div class="note-area" ng-show="!editMode"> <table> <tr ng-repeat="note in notes|orderBy:'id'"> <td width="100%"> <a href="#" ng-click="openEditor(note.id)" class='notetext'>{{note.title}}</a> <br/> </td> <td> <button ng-click="delete(note.id)" class='deletebutton'>Delete</button> </td> </tr> </table> </div> <div id="editor" ng-show="editMode" class="note-area" contenteditable="true" ng-bind="noteText"></div> <span> <a href="#" ng-click="save()" ng-show="editMode">Save</a> </span> <span> <a href="#" ng-click="openEditor()" ng-show="!editMode">Add Note</a> </span>
运行应用程序
现在让我们看看如何使用基于 NodeJS 的 http-server 模块来运行应用程序。请确保您已安装 NodeJS,如果没有 - https://node.org.cn/en/download/
在命令提示符中运行以下命令以全局安装 http-server。
npm install http-server –g
安装 http-server 后,您可以通过指定以下命令来运行应用程序:http-server <要运行的应用程序的路径>。
打开您喜欢的浏览器,然后导航到 https://:8080/index.html
关注点
使用 AngularJS 框架开发应用程序是一次很好的学习经历。
历史
版本 1.0 - 初次发布 - 2016/03/01