sails.js_使用Sails.js和AngularJS构建待办应用

sails.js

AngularJS is an increasingly popular MV*/MVVM Javascript front-end framework that seamlessly integrates with the server-side MVC Node.js framework, Sails.js. Although AngularJS is well known and prevalently used, Sails.js is a more up-and-coming framework.

AngularJS是一种越来越流行的MV * / MVVM Javascript前端框架,可与服务器端MVC Node.js框架Sails.js无缝集成。 尽管AngularJS是众所周知的并且被广泛使用,但是Sails.js是一个新兴的框架。

Sails.js is written in Node.js and utilizes Express as a web server. Additionally, Sails.js comes bundled with Waterline ORM simplifying the data layer by you only having to interchange adapters for most SQL or NoSQL databases.

Sails.js用Node.js编写,并利用Express作为Web服务器。 此外,Sails.js与Waterline ORM捆绑在一起,只需交换大多数SQL或NoSQL数据库的适配器,即可简化数据层。

One of my favorite features is the automatically generated REST API. This is very handy and allows you to create simple and well-designed APIs.

我最喜欢的功能之一是自动生成的REST API。 这非常方便,使您可以创建简单且设计良好的API。

Lastly, it is compatible with many popular front-end frameworks, including AngularJS, Backbone, Ember, iOS, Android, and many more. If you've been deciding on which Javascript framework you want to learn - Sails.js is simple, secure, and most of all, fun!

最后,它与许多流行的前端框架兼容,包括AngularJS,Backbone,Ember,iOS,Android等。 如果您一直在确定要学习的Javascript框架,那么Sails.js既简单,安全,又非常有趣!

Whether you're a novice or veteran to AngularJS or Sails.js this blog post will illustrate how both frameworks interact with each other by building a to-do application.

无论您是AngularJS还是Sails.js的新手或老手,此博客都将通过构建待办事项应用程序来说明两个框架之间如何进行交互。

To see the full source code of this project, check it out here.

要查看该项目的完整源代码,请在此处查看

入门 (Getting Started)

安装依赖项 (Installing Dependencies)

Before jumping into the code, we will need to install npm (which additionally installs Node.js) to utilize the necessary packages for this tutorial. With npm installed, we need to grab the Sails.js dependency by running:

在跳入代码之前,我们将需要安装npm (它还会安装Node.js )以利用本教程所需的软件包。 安装npm后,我们需要通过运行以下代码来获取Sails.js依赖项:

$ npm install -g sails

Now let's generate a Sails.js application by using the sails CLI, sails new todoApp. Hopefully, your directory structure looks like this:

现在,让我们通过使用sails CLI, sails new todoApp来生成Sails.js应用程序。 希望您的目录结构如下所示:

│   Gruntfile.js
│   README.md
│   app.js
│   package.json
└─── api
    └───controllers
    └───models
    └─── policies
        │   sessionAuth.js
        │   responses
        │   badRequest.js
        │   forbidden.js
        │   notFound.js
        │   ok.js
        │   serverError.js
        │   services
    └─── assets
        │   favicon.ico
        │   images
        │   js
        │   robots.txt
        │   styles
        │   templates
    └─── images
    └─── js
        └─── dependencies
            │   sails.io.js
    └─── styles
        │   importer.less
    └─── templates
└─── config
    │   blueprints.js
    │   bootstrap.js
    │   connections.js
    │   cors.js
    │   csrf.js
    │   env
    │   globals.js
    │   http.js
    │   i18n.js
    │   local.js
    │   locales
    │   log.js
    │   models.js
    │   policies.js
    │   routes.js
    │   session.js
    │   sockets.js
    │   views.js
    └─── env
        │   development.js
        │   production.js
    └─── locales
        │   _README.md
        │   de.json
        │   en.json
        │   es.json
        │   fr.json

└─── node_modules
    └─── ejs
    └─── grunt
    └─── grunt-contrib-clean
    └─── grunt-contrib-coffee
    └─── grunt-contrib-concat
    └─── grunt-contrib-copy
    └─── grunt-contrib-cssmin
    └─── grunt-contrib-jst
    └─── grunt-contrib-less
    └─── grunt-contrib-uglify
    └─── grunt-contrib-watch
    └─── grunt-sails-linker
    └─── grunt-sync
    └─── include-all
    └─── rc
    └─── sails
    └─── sails-disk

└─── tasks
    │   README.md
    │   pipeline.js
    └─── config
        │   clean.js
        │   coffee.js
        │   concat.js
        │   copy.js
        │   cssmin.js
        │   jst.js
        │   less.js
        │   sails-linker.js
        │   sync.js
        │   uglify.js
        │   watch.js
    └─── register
        │   build.js
        │   buildProd.js
        │   compileAssets.js
        │   default.js
        │   linkAssets.js
        │   linkAssetsBuild.js
        │   linkAssetsBuildProd.js
        │   prod.js
        │   syncAssets.js
└─── views
        │   403.ejs
        │   404.ejs
        │   500.ejs
        │   homepage.ejs
        │   layout.ejs

Great! Now we can start our server with sails lift and see our landing page by visiting http://localhost:1337.

大! 现在,我们可以使用sails lift启动服务器,并通过访问http:// localhost:1337来查看登录页面。

sails-new-app

Additionally, we need to update our package.json and create a bower.json file to configure the project to our needs.

此外,我们需要更新package.json并创建bower.json文件,以根据需要配置项目。

package.json (package.json)

Let's update the package.json file to have the following packages. Optionally, you can edit the name, author, and many other properties of this file to fit your needs.

让我们更新package.json文件,使其具有以下软件包。 (可选)您可以编辑此文件的名称,作者和许多其他属性,以满足您的需要。

{
  "name": "todoApp",
  "author": "Scotch",
  "description": "Sails/Angular Todo Applcation",
  "main": "app.js",
  "dependencies": {
    "bower": "^1.4.1",
    "ejs": "~0.8.4",
    "forever": "^0.11.1",
    "grunt": "0.4.2",
    "grunt-contrib-clean": "~0.5.0",
    "grunt-contrib-coffee": "~0.10.1",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-copy": "~0.5.0",
    "grunt-contrib-cssmin": "~0.9.0",
    "grunt-contrib-jst": "~0.6.0",
    "grunt-contrib-less": "0.11.1",
    "grunt-contrib-uglify": "~0.4.0",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-sails-linker": "~0.9.5",
    "grunt-sync": "~0.0.4",
    "include-all": "~0.1.3",
    "q": "^1.4.1",
    "rc": "~0.5.0",
    "sails": "~0.11.0",
    "sails-disk": "~0.10.0"
  }
}

To install these dependencies, run npm install. Now, we need to customize our front-end configuration. Under the assets directory, run bower init to generate the bower.json file, update it with the following packages and install them with bower install:

要安装这些依赖项,请运行npm install 。 现在,我们需要自定义前端配置。 在assets目录下,运行bower init生成bower.json文件,使用以下软件包对其进行更新,并使用bower install

bower.json (bower.json)

{
  "name": "todoAngularApp",
  "dependencies": {
    "angular-bootstrap": "~0.11.0",
    "angular-moment": "~0.7.1",
    "angular-route": "~1.2.17",
    "angular": "1.2.19",
    "angular-mocks": "~1.2.21",
    "jquery": "~2.1.3",
    "bootstrap": "~3.3.5"
  }
}

One last thing we need to set up is in the tasks/pipeline.js. Pipeline.js tells our program where our dependencies are and which to load.

我们需要设置的最后一件事是在task / pipeline.js中 。 Pipeline.js告诉我们的程序我们的依赖项在哪里以及要加载哪些依赖项。

pipeline.js (pipeline.js)

var cssFilesToInject = [
'bower_components/bootswatch/dist/css/bootstrap.css',
'styles/**/*.css'
];
var jsFilesToInject = [
  'js/dependencies/sails.io.js',
  '/bower_components/jquery/dist/jquery.js',
  '/bower_components/angular/angular.js',
  '/bower_components/angular-route/angular-route.js',
  '/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js',
  '/bower_components/bootstrap/dist/js/boostrap.js',
  'js/dependencies/**/*.js',

  'js/**/*.js'
  ];

var templateFilesToInject = [
'templates/*.html'
];

module.exports.cssFilesToInject = cssFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.jsFilesToInject = jsFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.templateFilesToInject = templateFilesToInject.map(function(path) {
  return 'assets/' + path;
});

Now with the configuration set up, we can dive into the coding!

现在完成配置,我们可以开始编码了!

前端 (Front-end)

Layout.ejs (Layout.ejs)

Typically, we need to add a ng-app tag in our HTML, but this needs to be in our views/layout.ejs file. The layout.ejs is where our script and stylesheet tags are and the templating structure. Let's modify the HTML tag to look like this: <html ng-app="todoApp">.

通常,我们需要在HTML中添加ng-app标签,但这需要在views / layout.ejs文件中。 layout.ejs是我们的脚本和样式表标签所在的位置以及模板结构。 让我们将HTML标记修改如下: <html ng-app="todoApp">

app.js (app.js)

Now this is where the actual AngularJS programming comes in. Create assets/js/app.js. The app.js is going to be our primary controller as well as instantiate our angular module. Also, we need to include a method for retrieving all the todos (on page load), adding and remove a todo.

现在这是实际的AngularJS编程的来源。创建asset / js / app.js。 app.js将成为我们的主要控制器,并实例化我们的angular模块。 另外,我们需要包括一种用于检索所有待办事项(页面加载时),添加和删除待办事项的方法。

'use strict';

var todoApp = angular.module('todoApp', ['ngRoute', 'ui.bootstrap']);
todoApp.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.when('/', {
      templateUrl: '/templates/todo.html',
      controller: 'TodoCtrl'
    }).otherwise({
      redirectTo: '/',
      caseInsensitiveMatch: true
    })
  }]);

todoApp.controller('TodoCtrl', ['$scope', '$rootScope', 'TodoService', function($scope, $rootScope, TodoService) {
  $scope.formData = {};
  $scope.todos = [];

  TodoService.getTodos().then(function(response) {
    $scope.todos = response;
  });

  $scope.addTodo = function() {
    TodoService.addTodo($scope.formData).then(function(response) {
      $scope.todos.push($scope.formData)
      $scope.formData = {};
    });
  }

  $scope.removeTodo = function(todo) {
    TodoService.removeTodo(todo).then(function(response) {
      $scope.todos.splice($scope.todos.indexOf(todo), 1)
    });
  }
}]);

TodoService (TodoService)

Notice that we include a TodoService that we haven't created yet. The service will communicate to our backend via a REST API we will create. Create assets/js/service/TodoService.js with the following code:

请注意,我们包含一个尚未创建的TodoService。 该服务将通过我们将创建的REST API与后端通信。 使用以下代码创建assets / js / service / TodoService.js:

todoApp.service('TodoService', function($http, $q) {
  return {
    'getTodos': function() {
      var defer = $q.defer();
      $http.get('/todo/getTodos').success(function(resp){
        defer.resolve(resp);
      }).error( function(err) {
        defer.reject(err);
      });
      return defer.promise;
    },
    'addTodo': function(todo) {
      var defer = $q.defer();
      $http.post('/todo/addTodo', todo).success(function(resp){
        defer.resolve(resp);
      }).error( function(err) {
        defer.reject(err);
      });
      return defer.promise;
    },
    'removeTodo': function(todo) {
      var defer = $q.defer();
      $http.post('/todo/removeTodo', todo).success(function(resp){
        defer.resolve(resp);
      }).error( function(err) {
        defer.reject(err);
      });
      return defer.promise;
    }
}});

模板 (Template)

Last thing we need for our front-end is the HTML template that our client will see and interact with. Here is assets/templates/todo.html that we referenced in app.js

我们前端需要的最后一件事是客户端将看到并与之交互HTML模板。 这是我们在app.js中引用的assets / templates / todo.html

<div class="container" ng-controller="TodoCtrl as todo">
    <div class="jumbotron">
        <h1 align="center">Todo Application</h1>
        <br>
        <div id="todo-form" class="row">
            <div class="col-sm-8 col-sm-offset-2 text-center">

            </div>
        </div>
    </div>
    <div id="todo-list" class="row">
        <div class="col-sm-4 col-sm-offset-4">
            <div class="checkbox" ng-repeat="singleTodo in todos">
                <label>
                    <input type="checkbox" ng-click="todo.removeTodo(singleTodo)">
                    {{ singleTodo.value }}
                </label>
            </div>
        </div>
    </div>
</div>

前端和后端之间的数据流 (Data Flow Between the Front and Back End)

One of the most challenging concepts new Sails.js developers has is determining how data flows between the front and back end. Let's break down this process starting with the front-end using our application as an example.

Sails.js新开发人员最具挑战性的概念之一就是确定数据在前端和后端之间如何流动。 让我们以我们的应用程序为例,从前端开始分解这个过程。

Let's say the user creates a todo from the view on the front-end. The logic that controls this part is located in the controller ($scope.addTodo function). Notice how this calls the service which uses the $http service to make an HTTP POST request to the URL http://localhost:1337/todo/addTodo

假设用户从前端的视图中创建了一个待办事项。 控制该部分的逻辑位于控制器中( $scope.addTodo函数)。 请注意,这是如何调用使用$http服务的服务以对URL http:// localhost:1337 / todo / addTodo发出HTTP POST请求的

This is where Sails.js comes into play (further described below). The controller recognizes the addTodo request and in the TodoController, it communicates with the TodoService with the given todo information. Next, the service interacts with the todo model defined in Todo.js.

这就是Sails.js发挥作用的地方(下文进一步介绍)。 控制器识别所述addTodo请求和TodoController ,它与通信TodoService与给定的待办事项信息。 接下来,该服务与Todo.js定义的todo模型进行Todo.js

After updating the model, any errors or callback functions travel upstream to where the user can eventually see their newly created todo! This picture accurately sums up the communication between both, the front and back end.

更新模型后,所有错误或回调函数都会向上游传播,最终用户可以看到他们新创建的待办事项! 此图片准确总结了前端和后端之间的通信。

frontend-to-backend-sails-angular

后端 (Back-end)

Firstly, we need to create a model that will store our todos. This object will only hold the todo value and will be stored in the Waterline ORM. All the back-end code will be in the api directory. Lastly, the data flows from the controller to service to model and back up.

首先,我们需要创建一个模型来存储待办事项。 该对象将仅保留todo值,并将存储在Waterline ORM中 。 所有后端代码都将在api目录中。 最后,数据从控制器流向服务以进行建模和备份。

We can use the sails cli to create a model and controller skeleton. Let's do this by sails generate api Todo.

我们可以使用sails cli创建模型和控制器骨架。 让我们通过sails generate api Todo做到这一点。

Here is the model located at api/models/Todo.js:

这是位于api / models / Todo.js的模型

模型 (Model)

module.exports = {
  attributes: {
    value: {
      'type': 'text'
    }
  }
};

控制者 (Controller)

Now we need to have a controller that our service in the front-end can communicate with through the Sails.js generated API. Note that each of the functions must be the same name as the front-end service functions. Here is the controller located at api/controllers/TodoController.js:

现在,我们需要一个控制器,前端的服务可以通过Sails.js生成的API与之通信。 请注意,每个功能必须与前端服务功能具有相同的名称。 这是位于api / controllers / TodoController.js的控制器

module.exports = {
    getTodos: function(req, res) {
        TodoService.getTodos(function(todos) {
            res.json(todos);
        });
    },
    addTodo: function(req, res) {
        var todoVal = (req.body.value) ? req.body.value : undefined
        TodoService.addTodo(todoVal, function(success) {
            res.json(success);
        });
    },
    removeTodo: function(req, res) {
       var todoVal = (req.body.value) ? req.body.value : undefined
        TodoService.removeTodo(todoVal, function(success) {
            res.json(success);
        });
    };
};

服务 (Service)

Lastly, we have the service that is the middleware between the controller and model. In this service, we use the Waterline ORM syntax to use CRUD operations on the model. Here is the service located at api/services/TodoService.js:

最后,我们提供的服务是控制器和模型之间的中间件。 在此服务中,我们使用Waterline ORM语法在模型上使用CRUD操作。 这是位于api / services / TodoService.js的服务

module.exports = {
  getTodos: function(next) {
    Todo.find().exec(function(err, todos) {
      if(err) throw err;
      next(todos);
    });
  },
  addTodo: function(todoVal, next) {
    Todo.create({value: todoVal}).exec(function(err, todo) {
      if(err) throw err;
      next(todo);
    });
  },
  removeTodo: function(todoVal, next) {
    Todo.destroy({value: todoVal}).exec(function(err, todo) {
      if(err) throw err;
      next(todo);
    });
  }
};

起飞! (Lift Off!)

Now that we've finished the code let's take a look at our application! Once again, we can run our server by sails lift.

现在我们已经完成了代码,让我们看一下我们的应用程序! 再一次,我们可以通过sails lift运行服务器。

sails-angular-todo-application

And now by adding some todos, we got a nice list going! We can also remove them by checking them off.

现在,通过添加一些待办事项,我们得到了一个不错的清单! 我们也可以通过选中它们来删除它们。

sails-angular-todo-app-with-todos

结论 (Conclusion)

Sails.js and AngularJS supply extraordinary tools to implement SPAs. Additionally, using Sails.js will help create robust applications for larger applications such as enterprise applications.

Sails.js和AngularJS提供了非凡的工具来实现SPA。 此外,使用Sails.js将有助于为大型应用程序(例如企业应用程序)创建健壮的应用程序。

Hopefully, this small project has demystified developing applications in Sails.js and AngularJS.

希望这个小项目使在Sails.js和AngularJS中开发应用程序神秘化。

翻译自: https://scotch.io/tutorials/build-a-todo-app-using-sailsjs-and-angularjs

sails.js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值