рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдХреЙрдордирдЬреЗрдПрд╕


рд╣рдо рдХрд┐рд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ?


рдЬреЗрдПрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдФрд░ рд╕рд░реНрд╡рд░ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрдирдХреА рдмрд╛рддрдЪреАрдд рдФрд░ рдмрд╛рд╣рд░реА рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред рдХрдо рд╕рд┐рджреНрдзрд╛рдВрдд, рдЕрдзрд┐рдХ рдЕрднреНрдпрд╛рд╕ред рдпреБрд╡рд╛ рд╕реЗрдирд╛рдиреА рдкрд╛рдареНрдпрдХреНрд░рдо рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо Node.JS: ToDo-list рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рд╕рд░рд▓ рдФрд░ рдЙрдЪреНрдЪ рдореВрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдирд┐рдореНрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
  1. "рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдврд╛рдВрдЪреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░" рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдореЙрдбреНрдпреВрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ;
  2. рдЙрдиреНрд╣реЗрдВ рдордВрдЪ-рдирд┐рд░реНрднрд░ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╕рд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП;
  3. рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдПрдХ рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рд▓реЗрдпрд░ рдмрдирд╛рдПрдВ;
  4. ToDo рд╕реВрдЪреА рд▓реЗ рд▓реЛ;
  5. рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдПред


рдЖрд╡реЗрджрди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ


рд╣рдо рдкреВрд░реЗ рдЙрдкрдХреНрд░рдо рдХреЗ рд╕рд╛рд░ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓реЗрддреЗ рд╣реИрдВред рд╣рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ:
  1. рдЖрд╡реЗрджрди рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реБрд▓рдн рд╣реИ;
  2. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рд╕рддреНрд░ рдореЗрдВ рдЕрдкрдиреА ToDo-list рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЬрдм рдЖрдк рдкреГрд╖реНрда рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЯреИрдм рдпрд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╕реВрдЪреА рдХреЛ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП - рдПрдХ рдирдпрд╛ рдмрдирд╛рдПрдВ;
  3. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реВрдЪреА рдореЗрдВ рдирдП рдЖрдЗрдЯрдо рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИ;
  4. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЬреЛрдбрд╝реЗ рдЧрдП рдЖрдЗрдЯрдо рдХреЛ рдкреВрд░реНрдг рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред


рдлреНрд░реЗрдо рдмрдирд╛ рд▓реЗрдВ


рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛, рд╣рдо рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдврд╛рдВрдЪреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЖрд╡реЗрджрди рдХреЗ рдврд╛рдВрдЪреЗ рдХреЛ рдмрдврд╝рд╛рддреЗ рд╣реИрдВред рд╣рдо рдмреЙрдХреНрд╕ рд╕реЗ рдорд┐рд▓реА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВрдЧреЗ:
. тФЬтФАтФА bin тФЬтФАтФА client //     ,   тФЬтФАтФА modules //  , ,  CommonJS  тФЬтФАтФА public тФВ  тФФтФАтФА stylesheets тФЬтФАтФА routes тФФтФАтФА views 


рдЖрдЗрдП рд╡рд┐рд╖рдп рдХреНрд╖реЗрддреНрд░ рд╕реЗ рд╣рдорд╛рд░рд╛ рдкрд╣рд▓рд╛ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдПрдВ - рдкреНрд╡рд╛рдЗрдВрдЯ, рдЯреВрдбреЛ рд╕реВрдЪреА рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛:
 // modules/Point/Point.js /** *    * @param {Object} params * @param {String} params.description * @param {String} [params.id] * @param {Boolean} [params.isChecked] * @constructor */ function Point(params) { if (!params.description) { throw 'Invalid argument'; } this._id = params.id; this._description = params.description; this._isChecked = Boolean(params.isChecked); } Point.prototype.toJSON = function () { return { id: this._id, description: this._description, isChecked: this._isChecked }; } 

рдкреВрд░реА рддрд░рд╣ рд╕реЗ
 /** * @param {String} id */ Point.prototype.setId = function (id) { if (!id) { throw 'Invalid argument'; } this._id = id; } /** * @returns {String} */ Point.prototype.getId = function () { return this._id; } Point.prototype.check = function () { this._isChecked = true; } Point.prototype.uncheck = function () { this._isChecked = false; } /** * @returns {Boolean} */ Point.prototype.getIsChecked = function () { return this._isChecked; } /** * @returns {String} */ Point.prototype.getDescription = function () { return this._description; } module.exports = Point; 


рдЕрджреНрднреБрддред рдпрд╣ рд╣рдорд╛рд░рд╛ рдкрд╣рд▓рд╛ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдореЙрдбреНрдпреВрд▓ рд╣реИ рдФрд░ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд░реНрд╡рд░ рдкрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:
 // routes/index.js var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function (req, res) { var Point = require('../modules/Point'); var newPoint = new Point({ description: 'Do something' }); console.log('My new point:', newPoint); }); module.exports = router; 

рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдХреЙрдордирдЬрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдмреНрд░рд╛рдЙрдЬрд░-рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рд▓рд┐рдП рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╣реИ:
 // app.js // ... var browserify = require('browserify-middleware'); app.use('/client', browserify('./client')); // ... 

рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рд░рд▓ рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝рдХрд░, рд╣рдо рддреБрд░рдВрдд рдЕрдкрдиреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
 // client/todo.js var console = require('console'); //  `node_modules/browserify/node_modules/console-browserify` var Point = require('../modules/Point'); 


Browserify, Nodian рдореЙрдбреНрдпреВрд▓ рд▓реЛрдбрд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЛрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ рдХреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░-рдЖрдзрд╛рд░рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ ред рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдХреБрдЫ рд▓рд┐рдЦрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХреЗрд╡рд▓ рдЗрддрдирд╛ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдм /client/todo.js рдкрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЪрд╛рд▓реВ рд╣реИред

рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ


рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рдореИрдВрдиреЗ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╢рд░реНрдд рд╡рд┐рднрд╛рдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛:

рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдореЙрдбреНрдпреВрд▓
рдЙрдирдХреА рдорджрдж рд╕реЗ, рдбреЗрд╡рд▓рдкрд░ рдХреЛрдб рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдФрд░ рдмрдирд╛рдП рд░рдЦрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рд╡рд╛рджреЛрдВ рдХреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ, рд▓реЙрд╢ , рдХрдВрд╕реЛрд▓ред рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП, рдРрд╕реЗ рдореЙрдбреНрдпреВрд▓ рди рдХреЗрд╡рд▓ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдХрдИ рдмреВрдЯ рдкреНрд░рд╛рд░реВрдкреЛрдВ (рдХреЙрдордирдЬреЗрд╕, рдПрдПрдордбреА) рдХрд╛ рднреА рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред

рдбреЛрдореЗрди рдореЙрдбреНрдпреВрд▓
рдбреЛрдореЗрди рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░реЗрдВред рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдРрд╕рд╛ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдпрд╛ рд╣реИ - рдкреНрд╡рд╛рдЗрдВрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░, рдЬрд▓реНрдж рд╣реА рд╕реВрдЪреА рдореЙрдбреНрдпреВрд▓ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рд╣рдореЗрдВ рд╡рд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП (AddPoint, getPoints, checkPoint) рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдореЙрдбреНрдпреВрд▓, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рддреНрд░ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рдЗрд╕ рддрд░рд╣ рдХреЗ рдореЙрдбреНрдпреВрд▓ рджреЛрдиреЛрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо-рдбрд┐рдкреЗрдВрдбреЗрдВрдЯ рдкрд╛рд░реНрдЯреНрд╕ рд╣реЛрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рддрд░реАрдХреЗ рдпрд╛ рдЧреБрдг рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдЕрдХреНрд╕рд░ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо-рдирд┐рд░реНрднрд░ рднрд╛рдЧ рдореЙрдбреНрдпреВрд▓ рдХреА рдирд┐рдореНрди рд╢реНрд░реЗрдгреА рдореЗрдВ рдЖрддрд╛ рд╣реИред

рджрд╛рд▓ рдореЙрдбреНрдпреВрд▓ (рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рд▓реЗрдпрд░)
рдпреЗ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рдПрдХ рдордирдорд╛рдиреЗ рд╕реЗрдЯ рд╕реЗ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ (рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕, рд╕рдВрдЧреНрд░рд╣) рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдореЙрдбреНрдпреВрд▓ рд╣реИрдВред рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕реНрдерд╛рдиреАрдпрд╕реНрдЯреЛрд░реЗрдЬ, рд╕реЗрд╢рдирд╕реНрдЯреЛрд░реЗрдЬ, рдХреБрдХреАрдЬ, рдПрдХ рдмрд╛рд╣рд░реА рдПрдкреАрдЖрдИ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдкрд░ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ: рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдПрдХ рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛, рдПрдХ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдФрд░, рдлрд┐рд░ рд╕реЗ, рдХреБрдЫ рдмрд╛рд╣рд░реА рдПрдкреАрдЖрдИред

рдпрджрд┐ рд╡рд┐рд╖рдп рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдореЙрдбреНрдпреВрд▓ рдбреАрдПрдПрд▓ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рддрд╛ рд╣реИ, рддреЛ рдбреАрдПрдПрд▓ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдПрдХ рдПрдХрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдФрд░ рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ, рд╣рдо рдЗрд╕реЗ рдЙрдкрдпреЛрдЧреА рдмреНрд░рд╛рдЙрдЬрд░ рдлреАрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ , рдЬрд┐рд╕рдореЗрдВ рдкреИрдХреЗрдЬ.рдЬрд╕рди рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдбреЛрдореЗрди рдореЙрдбреНрдпреВрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рдбреАрдПрдПрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 { "name" : "dal", "main" : "./node.js", //     "browser": "./browser.js" //   browserify     } 


рд╣рдо рдореЙрдбреНрдпреВрд▓ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ


рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдореЙрдбреНрдпреВрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА? рдореЗрдордХрд╛рдЪреЗ рдХреЛ рд╕рд░реНрд╡рд░ рдкрд░ рднрдВрдбрд╛рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рджреЗрдВ, рдЗрд╕рдореЗрдВ рд╣рдо рдЕрдкрдиреЗ рдЯреВрдбреВ-рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкрд╣рдЪрд╛рди рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рд╣реЛрдЧреА, рд╣рдо рд╕рддреНрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рд╕реЗрд╢рдирд╕реНрдЯреЛрд░реЗрдЬ рдореЗрдВ рдбрд╛рд▓реЗрдВрдЧреЗ рдФрд░ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рд░реНрд╡рд░ рддрдХ рдкрд╣реБрдВрдЪрд╛рдПрдВрдЧреЗред рддрджрдиреБрд╕рд╛рд░, рд╕рд░реНрд╡рд░ рдкрд░ рд╣рдореЗрдВ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗ рдЗрд╕ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдЪреБрдирдирд╛ рд╣реЛрдЧрд╛ред

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдбреАрдПрдПрд▓ рд╕реНрддрд░ рдкрд░ рд╣рдореЗрдВ рд╕реЗрд╢рдирд╕реНрдЯреЛрд░реЗрдЬ рдФрд░ рдореЗрдореНрдЪреЗ рд╕реЗ рдмрд╛рддрдЪреАрдд рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рд╣рдо рдорд╛рдирдХ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ)ред
рдореЙрдбреНрдпреВрд▓ / рджрд╛рд▓ / рдмреНрд░рд╛рдЙрдЬрд╝рд░ / sessionStorage.js
 module.exports.set = function () { sessionStorage.setItem.apply(sessionStorage, arguments); } module.exports.get = function () { return sessionStorage.getItem.apply(sessionStorage, arguments); } 


рдореЙрдбреНрдпреВрд▓ / рджрд╛рд▓ / рдиреЛрдб / memcache.js
 var vow = require('vow'); var _ = require('lodash'); var memcache = require('memcache'); var client = new memcache.Client(21201, 'localhost'); var clientDefer = new vow.Promise(function(resolve, reject) { client .on('connect', resolve) .on('close', reject) .on('timeout', reject) .on('error', reject) .connect(); }); /** *    Memcache * @see {@link https://github.com/elbart/node-memcache#usage} * @param {String} clientMethod * @param {String} key * @param {*} [value] * @returns {vow.Promise} resolve with {String} */ function request(clientMethod, key, value) { var requestParams = [key]; if (!_.isUndefined(value)) { requestParams.push(value); } return new vow.Promise(function (resolve, reject) { requestParams.push(function (err, data) { if (err) { reject(err); } else { resolve(data); } }); clientDefer.then(function () { client[clientMethod].apply(client, requestParams); }, reject); }); } /** *     * @param {String} key * @param {*} value * @returns {vow.Promise} */ module.exports.set = function (key, value) { return request('set', key, value); } /** *     * @param {String } key * @returns {vow.Promise} resolve with {String} */ module.exports.get = function (key) { return request('get', key); } 


рдЕрдм рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЛрдореЗрди рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдореЗрдВ рдПрдХ рдПрдХрд▓ рдЧреЗрдЯрдЖрдИрдб рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд╕реНрддреБ рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛:
рдореЙрдбреНрдпреВрд▓ / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ / рджрд╛рд▓ / browser.js
 var storage = require('../../dal/browser/sessionStorage'); var key = 'todo_user_id'; /** *   id * @returns {String} */ function makeId() { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var i; for (i = 0; i < 10; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; } module.exports = { /** * @returns {String} */ getId: function () { var userId = storage.get(key); if (!userId) { userId = makeId(); storage.set(key, userId); } return userId; } }; 


рдореЙрдбреНрдпреВрд▓ / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ / рджрд╛рд▓ / рдиреЛрдб.рдЬреЗрдПрд╕
 var app = require('../../../app'); module.exports = { /** * @returns {String} */ getId: function () { return app.get('userId'); //     middleware } }; 


рдореЙрдбреНрдпреВрд▓ / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ / рджрд╛рд▓ / package.json
 { "name" : "dal", "main" : "./node.js", "browser": "./browser.js" } 


 // modules/user/user.js var dal = require('./dal'); //     ./dal/browser.js,   - ./dal/node.js function User() { } /** *    * @returns {String} */ User.prototype.getId = function () { return dal.getId(); } module.exports = new User(); 


рд╣рдо REST рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рд╣рдореЗрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ DAL рд╕реНрддрд░ рдкрд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
рдореЙрдбреНрдпреВрд▓ / рджрд╛рд▓ / рдмреНрд░рд╛рдЙрдЬрд╝рд░ / rest.js
 var vow = require('vow'); var _ = require('lodash'); /** *    REST API * @param {String} moduleName -   * @param {String} methodName -   * @param {Object} params -   * @param {String} method -   * @returns {vow.Promise} resolve with {Object} xhr.response */ module.exports.request = function (moduleName, methodName, params, method) { var url = '/api/' + moduleName + '/' + methodName + '/?', paramsData = null; if (_.isObject(params)) { paramsData = _.map(params, function (param, paramName) { return paramName + '=' + encodeURIComponent(param); }).join('&'); } if (method !== 'POST' && paramsData) { url += paramsData; paramsData = null; } return new vow.Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.responseType = 'json'; xhr.onload = function() { if(xhr.status === 200) { resolve(xhr.response); } else { reject(xhr.response || xhr.statusText); } }; xhr.send(paramsData); }); } 


рдФрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд░рд╛рдЙрдЯрд░ рдЬреЛ рд╣рдорд╛рд░реЗ рдбреЛрдореЗрди рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛:
 // routes/api.js // ... router.use('/:module/:method', function (req, res) { var module = require('../modules/' + req.params.module), method = module[req.params.method]; if (!method) { res.send(405); return; } method.apply(module, req.apiParams) .then(function (data) { res.json(data); }, function (err) { res.send(400, JSON.stringify(err)); }); }); // ... 

рдХрд╛рд░реНрдп рдХреА рд╢рд░реНрддреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдореЗрдВ рдПрдкреАрдЖрдИ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ:
  1. GET, / list / getPoints - рд╡рд░реНрддрдорд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА ToDo- рд╕реВрдЪреА рдореЗрдВ рдПрдХ рдЯреВ-рдбреВ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ;
  2. POST, / list / addPoint - рд╡рд░реНрддрдорд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА ToDo- рд╕реВрдЪреА рдореЗрдВ рдПрдХ рдирдпрд╛ рдЖрдЗрдЯрдо рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ;
  3. рдкреЛрд╕реНрдЯ, рд╕реВрдЪреА / рдЪреЗрдХрдкреЙрдЗрдВрдЯ - рдЖрдЗрдЯрдо рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░реЗрдВ рдЬреИрд╕рд╛ рдХрд┐ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ;

рдПрдХ рдирдпрд╛ рдЖрдЗрдЯрдо рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рд░рд╛рдЙрдЯрд░ рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд┐рдореНрдореЗрджрд╛рд░рд┐рдпрд╛рдВ рд╕реМрдВрдкрдиреА рд╣реЛрдВрдЧреА: рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдорд┐рд╢рди рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдирд╛:
 router.post('/list/addPoint', function (req, res, next) { var Point = require('../modules/Point'), point; req.apiParams = []; try { point = new Point(JSON.parse(req.param('point'))); req.apiParams.push(point); } catch (e) {} next(); }); 

рдареАрдХ рд╣реИ, рдЕрдм рд╣рдо рд╕реВрдЪреА рд╡рд┐рд╖рдп рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЕрдВрддрд┐рдо рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рдореЙрдбреНрдпреВрд▓ / рд╕реВрдЪреА / рджрд╛рд▓ / browser.js
 var _ = require('lodash'); var rest = require('../../dal/browser/rest'); var Point = require('../../Point'); module.exports = { /** * @param {User} user * @returns {vow.Promise} resolve with {Point[]} */ getPoints: function (user) { return rest.request('list', 'getPoints', {userId: user.getId()}, 'GET') .then(function (points) { return _.map(points, function (point) { return new Point(point); }); }); }, /** * @param {User} user * @param {Point} point * @returns {vow.Promise} resolve with {Point} */ addPoint: function (user, point) { var requestParams = { userId: user.getId(), point: JSON.stringify(point) }; return rest.request('list', 'addPoint', requestParams, 'POST') .then(function (point) { return new Point(point); }); }, /** * @param {User} user * @param {Point} point * @returns {vow.Promise} */ checkPoint: function (user, point) { var requestParams = { userId: user.getId(), pointId: point.getId() }; return rest.request('list', 'checkPoint', requestParams, 'POST'); } }; 


рдореЙрдбреНрдпреВрд▓ / рд╕реВрдЪреА / рджрд╛рд▓ / рдиреЛрдб.рдЬреЗрдПрд╕
 var _ = require('lodash'); var memcache = require('../../dal/node/memcache'); var Point = require('../../Point'); /** *       * @param {User} user * @returns {String} */ function getListKey(user) { return 'list_' + user.getId(); } module.exports = { /** * @param {User} user * @returns {vow.Promise} resolve with {Point[]} */ getPoints: function (user) { return memcache.get(getListKey(user)) .then(function (points) { if (points) { try { points = _.map(JSON.parse(points), function (point) { return new Point(point); }); } catch (e) { points = []; } } else { points = []; } return points; }); }, /** * @param {User} user * @param {Point} point * @returns {vow.Promise} resolve with {Point} */ addPoint: function (user, point) { return this.getPoints(user) .then(function (points) { point.setId('point_' + (new Date().getTime())); points.push(point); return memcache.set(getListKey(user), JSON.stringify(points)) .then(function () { return point; }); }); }, /** * @param {User} user * @param {Point} point * @returns {vow.Promise} */ checkPoint: function (user, point) { return this.getPoints(user) .then(function (points) { var p = _.find(points, function (p) { return p.getId() === point.getId(); }); if (!p) { throw 'Point not found'; } p.check(); return memcache.set(getListKey(user), JSON.stringify(points)); }); } }; 


рдореЙрдбреНрдпреВрд▓ / рд╕реВрдЪреА / рджрд╛рд▓ / package.js
 { "name" : "dal", "main" : "./node.js", "browser": "./browser.js" } 


 // modules/list/list.js //   var _ = require('lodash'); var vow = require('vow'); var console = require('console'); // DAL- var dal = require('./dal'); //    var Point = require('../Point'); var user = require('../user'); var list = {}; var cache = {}; //   /** *       * @param {Point} newPoint * @returns {vow.Promise} resolve with {Point} */ list.addPoint = function (newPoint) { /* ... */ } /** *     * @param {String} pointId * @returns {vow.Promise} */ list.checkPoint = function (pointId) { /* ... */ } /** *      * @returns {vow.Promise} resolve with {Point[]} */ list.getPoints = function () { console.log('list / getPoints'); return new vow.Promise(function (resolve, reject) { var userId = user.getId(); if (_.isArray(cache[userId])) { resolve(cache[userId]); return; } dal.getPoints(user) .then(function (points) { cache[userId] = points; console.log('list / getPoints: resolve', cache[userId]); resolve(points); }, reject); }); } module.exports = list; 

рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд░реВрдк рд╕реЗ, рд╣рдорд╛рд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдореЙрдбреНрдпреВрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдиреЗ рд▓рдЧреЗ:
 modules тФЬтФАтФА dal тФВ  тФЬтФАтФА browser тФВ  тФВ  тФЬтФАтФА rest.js тФВ  тФВ  тФФтФАтФА sessionStorage.js тФВ  тФФтФАтФА node тФВ  тФФтФАтФА memcache.js тФЬтФАтФА list тФВ  тФЬтФАтФА dal тФВ  тФВ  тФЬтФАтФА browser.js //  dal/browser/rest.js тФВ  тФВ  тФЬтФАтФА node.js //  dal/node/memcache.js тФВ  тФВ  тФФтФАтФА package.json тФВ  тФЬтФАтФА list.js тФВ  тФФтФАтФА package.json тФЬтФАтФА Point тФВ  тФЬтФАтФА package.json тФВ  тФФтФАтФА Point.js тФФтФАтФА user тФЬтФАтФА dal тФВ  тФЬтФАтФА browser.js //  dal/browser/sessionStorage.js тФВ  тФЬтФАтФА node.js тФВ  тФФтФАтФА package.json тФЬтФАтФА package.json тФФтФАтФА user.js 


рд╕рднреА рдПрдХ рд╕рд╛рде


рдпрд╣ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреЗ рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдЯреВрдбреВ рд╕реВрдЪреА рдореЗрдВ рдПрдХ рдирдпрд╛ рдЖрдЗрдЯрдо рдЬреЛрдбрд╝рдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
 // client/todo.js // ... //    -           var console = require('console'); var _ = require('lodash'); var list = require('../modules/list'); var Point = require('../modules/Point'); var todo = { addPoint: function (description) { var point = new Point({ description: description }); list.addPoint(point); } }; // ... 

рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм todo.addPoint ('рдЯреЗрд╕реНрдЯ') рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ? рдореИрдВ рдЖрд░реЗрдЦреЛрдВ рдореЗрдВ рдореБрдЦреНрдп рдЪрд░рдгреЛрдВ рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдХреА рдмрд╛рддрдЪреАрдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
рдЪрд╛рд░реНрдЯ


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╕реВрдЪреА рдореЙрдбреНрдпреВрд▓ 2 рдмрд╛рд░ рдЕрдкрдиреЗ рдбреАрдПрдПрд▓ рдореЙрдбреНрдпреВрд▓ рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП http рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд╕рдорд╛рди (рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП) рдореЙрдбреНрдпреВрд▓ рдХреА рдкрд░рд╕реНрдкрд░ рдХреНрд░рд┐рдпрд╛ рдХреИрд╕реЗ рд╣реЛрддреА рд╣реИ:
рдмрдбрд╝рд╛ рдЪрд╛рд░реНрдЯ


рдпрд╣рд╛рдВ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ: рдбреЛрдореЗрди рдореЙрдбреНрдпреВрд▓ рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдФрд░ рд╕рд░реНрд╡рд░ рдкрд░ рдбреАрдПрдПрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмреАрдЪ рдмрд╛рддрдЪреАрдд рдпреЛрдЬрдирд╛ рд╕рдорд╛рди рд╣реИред DAL рд╕реНрддрд░ рдкрд░ рд╕рдВрдЪрд╛рд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдФрд░ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдереАред

рдЖрдЗрдЯрдо рдХреЗ рд╕реНрдЯреНрд░рд╛рдЗрдХрдереНрд░реВ рдХреЗ рд╕рд╛рде рдорд╛рдорд▓рд╛ рдЗрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛:
 list.checkPoint(pointId); 

рдмрд╕ рдХреБрдЫ рдорд┐рдирдЯ - рдФрд░ рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди рддреИрдпрд╛рд░ рд╣реИред
рдХреЛрдб: рдкрдардиреАрдп?
 // client/todo.js (function () { var console = require('console'); var _ = require('lodash'); var list = require('../modules/list'); var Point = require('../modules/Point'); var listContainer = document.getElementById('todo_list'); var newPointContainer = document.getElementById('todo_new_point_description'); var tmpl = '<ul>' + '<% _.forEach(points, function(point) { %>' + '<li data-id="<%- point.getId() %>" data-checked="<%- point.getIsChecked() ? 1 : \'\' %>" class="<% if (point.getIsChecked()) { %>todo_point_checked <% }; %>">' + '<%- point.getDescription() %>' + '</li><% }); %>' + '</ul>'; var todo = { addPoint: function (description) { var point = new Point({ description: description }); list.addPoint(point) .then(todo.render, todo.error); }, checkPoint: function (pointId) { list.checkPoint(pointId) .then(todo.render, todo.error); }, render: function () { list.getPoints() .then(function (points) { listContainer.innerHTML = _.template(tmpl, { points: points }); }); }, error: function (err) { alert(err); } }; newPointContainer.addEventListener('keyup', function (ev) { if (ev.keyCode == 13 && ev.ctrlKey && newPointContainer.value) { todo.addPoint(newPointContainer.value); newPointContainer.value = ''; } }); listContainer.addEventListener('click', function (ev) { var targetData = ev.target.dataset; if (!targetData.checked) { console.debug(targetData.checked); todo.checkPoint(targetData.id); } }); todo.render(); })(); 


рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдХреЛрдб : рдЬреАрдердм ред

рд╕рдордЭ


рдХреНрдпреЛрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╕рдм рдмрд╛рддрдЪреАрдд? рдлрд┐рд▓рд╣рд╛рд▓, рдореБрдЭреЗ рдХрд┐рдП рдЧрдП рдХрд╛рдо рд╕реЗ рдХреБрдЫ рдиреИрддрд┐рдХ рд╕рдВрддреБрд╖реНрдЯрд┐ рдорд┐рд▓реА рд╣реИ рдФрд░ рдЗрд╕рдХреА рдЙрдкрдпреБрдХреНрддрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрдИ рд╕рд╡рд╛рд▓ рд╣реИрдВред рдпрд╣ рдореЙрдбрд▓ рдЬрдЯрд┐рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рддрдирд╛ рдЙрдкрдпреБрдХреНрдд рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЖрд╡реЗрджрди рдХреА рд╕реАрдорд╛рдПрдБ рдХрд╣рд╛рдБ рд╣реИрдВ? рдХреНрдпрд╛ рдореИрдВ рдЕрдкрд░рд┐рд╣рд╛рд░реНрдп рдУрд╡рд░рд╣реЗрдб рдХреЗ рд╕рд╛рде рддреИрдпрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реВрдВ рдЬреЛ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдореЙрдбреНрдпреВрд▓ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реЛрдЧрд╛?

рдЬрдм рддрдХ рдкреВрд░реА рд╕рдордЭ рджреВрд░ рд╣реИред рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреБрдЫ рд╕рдорд╛рди рдХрд░рдиреЗ рдФрд░ рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реИред рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдЪреМрдЦрдЯреЗ рдФрд░ рдШрдЯрдХ рдкрд░реАрдХреНрд╖рдг - рдХреНрдпреЛрдВ рдирд╣реАрдВ?

Source: https://habr.com/ru/post/In222261/


All Articles