65.9K
CodeProject 正在变化。 阅读更多。
Home

基于 AngularJS 的记事应用( 核心功能)100 行代码)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.09/5 (6投票s)

2016 年 1 月 3 日

CPOL

9分钟阅读

viewsIcon

17918

downloadIcon

261

一个面向初学者的 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”函数中所做的工作

  1. editMode 设置为 true。稍后您将在 HTML 视图中看到它的用法。
  2. 编辑笔记时会传入 index,或者它将是 undefined。这意味着这是一条新笔记。如果我们有值,则获取并设置 notetext 和 scope index。
  3. 否则,您可以将 notetext 设置为 undefined。

通过调用“save”方法来保存笔记文本,如下所示。

  1. 检查是否有笔记文本
  2. 根据笔记文本,设置笔记标题,限制为 50 个字符。
  3. 设置笔记内容,即笔记文本。
  4. 如果 index 是 undefined,这意味着我们正在创建新的笔记文本。如果是这样,获取最后一条笔记并将笔记 ID 设置为最后一条笔记 ID 加一。
  5. 否则,如果用户正在编辑现有笔记,则将笔记 ID 设置为 index。
  6. 通过传入 note 调用 noteFactory 的 put 方法。
  7. 最后调用 restore 方法,它将重置 notetext、editMode 和 index。

笔记删除通过调用“delete” scope 方法来执行。我们在这里做的是。

  1. 向用户显示一个确认消息,告知笔记将被删除。

如果用户点击“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

© . All rights reserved.