-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Model impl #7
base: master
Are you sure you want to change the base?
Model impl #7
Changes from all commits
cafbd51
5c14151
39c6597
4cfc680
397bb96
1fdef83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
node_modules | ||
js/result.js | ||
.idea |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,68 +8,82 @@ | |
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css"> | ||
<!-- CSS overrides - remove if you don't need it --> | ||
<link rel="stylesheet" href="css/app.css"> | ||
<script src="js/view.js"></script> | ||
</head> | ||
<body> | ||
<section class="todoapp"> | ||
<header class="header"> | ||
<h1>todos</h1> | ||
<input class="new-todo" placeholder="What needs to be done?" autofocus> | ||
</header> | ||
|
||
|
||
<!-- This section should be hidden by default and shown when there are todos --> | ||
<section class="main"> | ||
<input class="toggle-all" type="checkbox"> | ||
<label for="toggle-all">Mark all as complete</label> | ||
<ul class="todo-list"> | ||
<!-- These are here just to show the structure of the list items --> | ||
<!-- List items should get the class `editing` when editing and `completed` when marked as completed --> | ||
<li class="completed"> | ||
<div class="view"> | ||
<input class="toggle" type="checkbox" checked> | ||
<label>Taste JavaScript</label> | ||
<button class="destroy"></button> | ||
</div> | ||
<input class="edit" value="Create a TodoMVC template"> | ||
</li> | ||
<li> | ||
<div class="view"> | ||
<input class="toggle" type="checkbox"> | ||
<label>Buy a unicorn</label> | ||
<button class="destroy"></button> | ||
</div> | ||
<input class="edit" value="Rule the web"> | ||
</li> | ||
<script id="todo" type="text/x-handlebars-template"> | ||
{{#each todo}} | ||
<li> | ||
<div class="view"> | ||
<input class="toggle" type="checkbox"> | ||
<label>{{name}}</label> | ||
<button class="destroy"></button> | ||
</div> | ||
<input class="edit" value="Create a TodoMVC template"> | ||
</li> | ||
{{/each}} | ||
</script> | ||
<!--<li class="completed">--> | ||
<!--<div class="view">--> | ||
<!--<input class="toggle" type="checkbox" checked>--> | ||
<!--<label>Taste JavaScript</label>--> | ||
<!--<button class="destroy"></button>--> | ||
<!--</div>--> | ||
<!--<input class="edit" value="Create a TodoMVC template">--> | ||
<!--</li>--> | ||
<!--<li>--> | ||
<!--<div class="view">--> | ||
<!--<input class="toggle" type="checkbox">--> | ||
<!--<label>Buy a unicorn</label>--> | ||
<!--<button class="destroy"></button>--> | ||
<!--</div>--> | ||
<!--<input class="edit" value="Rule the web">--> | ||
<!--</li>--> | ||
</ul> | ||
</section> | ||
<!-- This footer should hidden by default and shown when there are todos --> | ||
<footer class="footer"> | ||
<!-- This should be `0 items left` by default --> | ||
<span class="todo-count"><strong>0</strong> item left</span> | ||
<script id="item_left" type="text/x-handlebars-template"> | ||
<span class="todo-count"><strong>{{left}}</strong> item left</span> | ||
</script> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Лучше описать все шаблоны в одном месте, не вкладывая их в другие элементы. Например в head. |
||
<!-- Remove this if you don't implement routing --> | ||
<ul class="filters"> | ||
<li> | ||
<a class="selected" href="#/">All</a> | ||
</li> | ||
<li> | ||
<a href="#/active">Active</a> | ||
</li> | ||
<li> | ||
<a href="#/completed">Completed</a> | ||
</li> | ||
</ul> | ||
<!--<ul class="filters">--> | ||
<!--<li>--> | ||
<!--<a class="selected" href="#/">All</a>--> | ||
<!--</li>--> | ||
<!--<li>--> | ||
<!--<a href="#/active">Active</a>--> | ||
<!--</li>--> | ||
<!--<li>--> | ||
<!--<a href="#/completed">Completed</a>--> | ||
<!--</li>--> | ||
<!--</ul>--> | ||
<!-- Hidden if no completed items are left ↓ --> | ||
<button class="clear-completed">Clear completed</button> | ||
<!--<button class="clear-completed">Clear completed</button>--> | ||
</footer> | ||
</section> | ||
<footer class="info"> | ||
<p>Double-click to edit a todo</p> | ||
<!-- Remove the below line ↓ --> | ||
<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p> | ||
<!--<p>Double-click to edit a todo</p>--> | ||
<!-- Change this out with your name and url ↓ --> | ||
<p>Created by <a href="http://todomvc.com">you</a></p> | ||
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> | ||
<p>Created by <a href="https://github.com/EJohnF/">Evstropov Evgenii</a></p> | ||
</footer> | ||
<!-- Scripts here. Don't remove ↓ --> | ||
<script src="node_modules/todomvc-common/base.js"></script> | ||
<script src="js/app.js"></script> | ||
<script src="js/result.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
'use strict'; | ||
export default class EventEmitter { | ||
listeners = {}; | ||
observables = {}; | ||
|
||
/* | ||
methods for observable object | ||
*/ | ||
// subscribe to event | ||
on(eventName, handler) { | ||
if (typeof this.listeners[eventName] === 'undefined') { | ||
this.listeners[eventName] = []; | ||
} | ||
this.listeners[eventName].push(handler); | ||
} | ||
// rise the event | ||
emit(eventName, ...args) { | ||
if (typeof this.listeners[eventName] !== 'undefined') { | ||
this.listeners[eventName].forEach(func => { | ||
func(eventName, ...args); | ||
}); | ||
} | ||
} | ||
//unsubscribe from event | ||
off(eventName, handler) { | ||
if (typeof this.listeners[eventName] !== 'undefined') { | ||
this.listeners[eventName] = this.listeners[eventName].filter(listen => handler != listen); | ||
} | ||
} | ||
//remove all subscribers | ||
removeAll(eventName) { | ||
delete this.listeners[eventName]; | ||
} | ||
|
||
/* | ||
methods for listener object | ||
*/ | ||
|
||
// connect handler method to listen eventName of observable object | ||
listenTo(observable, eventName, handler) { | ||
if (typeof observable.on === 'undefined' || | ||
typeof observable.off === 'undefined') { | ||
throw new Error('There are not "on" or "off" methods'); | ||
} | ||
observable.on(eventName, handler); | ||
if (typeof this.observables[eventName] === 'undefined') { | ||
this.observables[eventName] = []; | ||
} | ||
this.observables[eventName].push({observable, handler}); | ||
|
||
} | ||
|
||
unlistenFrom(observable, eventName) { | ||
observable.off(eventName, this.observables[eventName].handler); | ||
if (typeof this.observables[eventName] !== 'undefined') { | ||
this.observables[eventName] = this.observables[eventName].filter(obs => obs.observable !== observable); | ||
} | ||
} | ||
|
||
unlistenAll() { | ||
for (let key in this.observables) { | ||
this.observables[key].forEach(obs => obs.observable.off(key, obs.handler)); | ||
delete this.observables[key]; | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports={ | ||
save: (store)=>{ | ||
//TODO better to surround it by try-catch | ||
localStorage.setItem('store', JSON.stringify(store)); | ||
}, | ||
load: ()=>{ | ||
return JSON.parse(localStorage.getItem('store')); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ | |
'use strict'; | ||
|
||
// Your starting point. Enjoy the ride! | ||
// Write npm run watch-js to start coding | ||
|
||
})(window); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
'use strict'; | ||
const api = require('./api'); | ||
|
||
class Model { | ||
var store = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В es6 нельзя так инициализировать поля. Их надо заполнять в конструкторе. |
||
lastId: -1, | ||
todo: [ | ||
{ | ||
id: 0, | ||
name: 'task for test', | ||
isCompleted: false | ||
} | ||
] | ||
}; | ||
constructor(){ | ||
this.addTask = this.addTask.bind(this); | ||
this.removeTask = this.removeTask.bind(this); | ||
this.toggleTask = this.toggleTask.bind(this); | ||
this.removeAll = this.removeAll.bind(this); | ||
this.save = this.save.bind(this); | ||
this.load = this.load.bind(this); | ||
} | ||
addTask(name, isCompleted = true) { | ||
var id = this.store.lastId + 1; | ||
this.store.todo.push({id:id, name: name, isCompleted: isCompleted}); | ||
this.store.lastId = id; | ||
return id; | ||
} | ||
removeTask(id){ | ||
this.store.todo = this.store.todo.filter(todo => todo.id !== id); | ||
} | ||
toggleTask(id){ | ||
this.store.todo = this.store.map(todo =>{ | ||
if (todo!== id) | ||
return todo; | ||
else { | ||
todo.isCompleted = !todo.isCompleted; | ||
return todo; | ||
} | ||
}); | ||
} | ||
removeAll(){ | ||
this.store.todo = []; | ||
this.store.lastId = -1; | ||
} | ||
save(){ | ||
api.save(this.store); | ||
} | ||
load(){ | ||
this.store = api.load(); | ||
} | ||
|
||
} | ||
|
||
module.exports = Model; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const Handlebars = require('handlebars'); | ||
|
||
var source = $("todo").html(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ты обращаешься к элементу по id, а не по тегу. Нужно писать $("#todo") |
||
var template = Handlebars.compile(source); | ||
var context = { todo: [{name: "first task"}, {name:"second task"}] }; | ||
var html = template(context); | ||
$("document").append(html); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
{ | ||
"private": true, | ||
"dependencies": { | ||
"browserify": "^13.1.1", | ||
"handlebars": "^4.0.6", | ||
"todomvc-app-css": "^2.0.0", | ||
"todomvc-common": "^1.0.0" | ||
"todomvc-common": "^1.0.0", | ||
"watchify": "^3.7.0" | ||
}, | ||
"scripts": { | ||
"build-js": "browserify js/app.js > js/result.js", | ||
"watch-js": "watchify js/app.js -o js/result.js" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Скрипт добавлен в страницу, а через browserify ты его не прогнал.
Нужно добавить его сборку в package.json/scripts, либо сделать require в app.js (recommended).