Commit 81c8ad00 authored by Addy Osmani's avatar Addy Osmani

Merge pull request #1045 from pgilad/patch-2

Ampersand.js - extract methods to collection
parents b3400aee 48054b8c
......@@ -14,13 +14,12 @@ module.exports = State.extend({
initialize: function () {
// Listen to changes to the todos collection that will
// affect lengths we want to calculate.
this.listenTo(this.todos, 'change:completed change:title add remove', this.handleTodosUpdate);
this.listenTo(this.todos, 'change:completed add remove', this.handleTodosUpdate);
// We also want to calculate these values once on init
this.handleTodosUpdate();
// Listen for changes to `mode` so we can update
// the collection mode.
this.on('change:mode', this.handleModeChange, this);
this.listenTo(this, 'change:mode', this.handleModeChange);
},
collections: {
todos: Todos
......@@ -71,18 +70,17 @@ module.exports = State.extend({
// so they're easy to listen to and bind to DOM
// where needed.
handleTodosUpdate: function () {
var completed = 0;
var todos = this.todos;
todos.each(function (todo) {
if (todo.completed) {
completed++;
}
});
var total = this.todos.length;
// use a method we defined on the collection itself
// to count how many todos are completed
var completed = this.todos.getCompletedCount();
// We use `set` here in order to update multiple attributes at once
// It's possible to set directely using `this.completedCount = completed` ...
this.set({
completedCount: completed,
activeCount: todos.length - completed,
totalCount: todos.length,
allCompleted: todos.length === completed
activeCount: total - completed,
totalCount: total,
allCompleted: total === completed
});
},
handleModeChange: function () {
......
......@@ -30,6 +30,11 @@ module.exports = Collection.extend({
// and persist on change
this.on('all', this.writeToLocalStorage, this);
},
getCompletedCount: function() {
return this.reduce(function(total, todo){
return todo.completed ? ++total : total;
}, 0);
},
// Helper for removing all completed items
clearCompleted: function () {
var toRemove = this.filter(function (todo) {
......
......@@ -43,13 +43,12 @@ module.exports = State.extend({
initialize: function () {
// Listen to changes to the todos collection that will
// affect lengths we want to calculate.
this.listenTo(this.todos, 'change:completed change:title add remove', this.handleTodosUpdate);
this.listenTo(this.todos, 'change:completed add remove', this.handleTodosUpdate);
// We also want to calculate these values once on init
this.handleTodosUpdate();
// Listen for changes to `mode` so we can update
// the collection mode.
this.on('change:mode', this.handleModeChange, this);
this.listenTo(this, 'change:mode', this.handleModeChange);
},
collections: {
todos: Todos
......@@ -100,18 +99,17 @@ module.exports = State.extend({
// so they're easy to listen to and bind to DOM
// where needed.
handleTodosUpdate: function () {
var completed = 0;
var todos = this.todos;
todos.each(function (todo) {
if (todo.completed) {
completed++;
}
});
var total = this.todos.length;
// use a method we defined on the collection itself
// to count how many todos are completed
var completed = this.todos.getCompletedCount();
// We use `set` here in order to update multiple attributes at once
// It's possible to set directely using `this.completedCount = completed` ...
this.set({
completedCount: completed,
activeCount: todos.length - completed,
totalCount: todos.length,
allCompleted: todos.length === completed
activeCount: total - completed,
totalCount: total,
allCompleted: total === completed
});
},
handleModeChange: function () {
......@@ -188,6 +186,11 @@ module.exports = Collection.extend({
// and persist on change
this.on('all', this.writeToLocalStorage, this);
},
getCompletedCount: function() {
return this.reduce(function(total, todo){
return todo.completed ? ++total : total;
}, 0);
},
// Helper for removing all completed items
clearCompleted: function () {
var toRemove = this.filter(function (todo) {
......@@ -532,7 +535,7 @@ extend(Collection.prototype, BackboneEvents, {
} else if (targetProto.generateId) {
id = targetProto.generateId(attrs);
} else {
id = attrs[targetProto.idAttribute || 'id'];
id = attrs[targetProto.idAttribute || this.mainIndex];
}
// If a duplicate is found, prevent it from being added and
......@@ -1402,6 +1405,7 @@ _.extend(History.prototype, Events, {
module.exports = new History();
},{"backbone-events-standalone":20,"underscore":21}],16:[function(require,module,exports){
;window.ampersand = window.ampersand || {};window.ampersand["ampersand-router"] = window.ampersand["ampersand-router"] || [];window.ampersand["ampersand-router"].push("1.0.6");
var classExtend = require('ampersand-class-extend');
var Events = require('backbone-events-standalone');
var ampHistory = require('./ampersand-history');
......@@ -2870,6 +2874,7 @@ module.exports=require(12)
}).call(this);
},{}],22:[function(require,module,exports){
;window.ampersand = window.ampersand || {};window.ampersand["ampersand-state"] = window.ampersand["ampersand-state"] || [];window.ampersand["ampersand-state"].push("4.3.14");
var _ = require('underscore');
var BBEvents = require('backbone-events-standalone');
var KeyTree = require('key-tree-store');
......@@ -6243,6 +6248,9 @@ function getBindingFunc(binding) {
return '';
}
})();
var yes = binding.yes;
var no = binding.no;
var hasYesNo = !!(yes || no);
// storage variable for previous if relevant
var previousValue;
......@@ -6289,10 +6297,10 @@ function getBindingFunc(binding) {
};
} else if (type === 'booleanClass') {
// if there's a `no` case this is actually a switch
if (binding.no) {
return function (el, value, keyName) {
var yes = makeArray(binding.name || binding.yes || keyName);
var no = makeArray(binding.no);
if (hasYesNo) {
yes = makeArray(yes || '');
no = makeArray(no || '');
return function (el, value) {
var prevClass = value ? no : yes;
var newClass = value ? yes : no;
getMatches(el, selector).forEach(function (match) {
......@@ -6325,17 +6333,17 @@ function getBindingFunc(binding) {
};
} else if (type === 'toggle') {
// this doesn't require a selector since we can pass yes/no selectors
if (binding.yes && binding.no) {
if (hasYesNo) {
return function (el, value) {
getMatches(el, binding.yes).forEach(function (match) {
getMatches(el, yes).forEach(function (match) {
dom[value ? 'show' : 'hide'](match);
});
getMatches(el, binding.no).forEach(function (match) {
getMatches(el, no).forEach(function (match) {
dom[value ? 'hide' : 'show'](match);
});
};
} else {
return function (el, value) {
return function (el, value) {
getMatches(el, selector).forEach(function (match) {
dom[value ? 'show' : 'hide'](match);
});
......@@ -6374,6 +6382,7 @@ function getBindingFunc(binding) {
}
},{"ampersand-dom":42,"key-tree-store":43,"matches-selector":51}],42:[function(require,module,exports){
;window.ampersand = window.ampersand || {};window.ampersand["ampersand-dom"] = window.ampersand["ampersand-dom"] || [];window.ampersand["ampersand-dom"].push("1.2.6");
var dom = module.exports = {
text: function (el, val) {
el.textContent = getString(val);
......@@ -6396,7 +6405,8 @@ var dom = module.exports = {
},
removeClass: function (el, cls) {
if (el.classList) {
el.classList.remove(getString(cls));
cls = getString(cls);
if (cls) el.classList.remove(cls);
} else {
// may be faster to not edit unless we know we have it?
el.className = el.className.replace(new RegExp('(^|\\b)' + cls.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment