Показать сообщение отдельно
  #5 (permalink)  
Старый 22.08.2014, 11:16
Профессор
Отправить личное сообщение для WorM32 Посмотреть профиль Найти все сообщения от WorM32
 
Регистрация: 11.02.2014
Сообщений: 303

// jsDOC
function TodoApp(opt) {// лучше использовать полное options
    this.elem = opt.elem;
    this.taskList = new TaskList(this.elem);
    this.input = this.elem.find('.todo-name'); 
    this.elem.on('submit', '.todo-form', $.proxy(this.onFormSubmit, this)) //пропущена ;. Почему не просто this.onFormSubmit.bind(this)?

}
TodoApp.prototype = {
    constructor: TodoApp,
    onFormSubmit: function() { // параметр e
        if(this.input.val().trim() === '') { // this.input.val() в переменную, тк используется 2 раза.
            return false; // нет! только e.preventDefault. return false аналогично вызову e.preventDefault() и e.stopPropagation(), использовать stopPropagation плохой тон.
        }
        this.taskList.addTask(this.input.val());
        this.input.val('');
        return false;
    }
};
function TaskList(el) {
    var that = this;
    this.el = el; // el, elem - определись уже. к тому же el - это jQuery переменная, jQuery переменные лучше обозначать используя префикс $ (например, $el)
    this.list = el.find('.todo-list');
    this.tasks = [];
    this.list.on('dblclick', '.todo-task', function(e) { // неправильный подход. TaskList должен содержать коллекцию Task и оперерировать уже ими. Так что dbclick должен слушать и обарабывать Task.
        var task = $(e.currentTarget).data('task');
        var newName = prompt('', task.name);
        task.edit(newName);
    });
    this.list.on('change', '.todo-check', function(e) {
        var task = $(e.currentTarget).parent().data('task'); // parent() - зло
        task.onCheckChange();
    });
    this.list.on('click', '.todo-x', $.proxy(this.onXClick, this)); // это должно быть у Task во вьюхе
    this.el.on('click', '.todo-remove', $.proxy(this.onRemoveClick, this)) // ;

}
TaskList.prototype = {
    constructor: TaskList,
    addTask: function(name) {
        var li = $('<li/>').addClass('todo-task animated flash'); // неее. Должен быть TaskView, который будет этой хренью заниматься. А здесь должн создаваться модель Task и на основе модели TaskView
        this.list.append(li);
        var task = new Task(li, name);
        this.tasks.push(task);
        li.data('task', task); // не понятно, зачем засовывать в this.task и в data элемента. косяк
        console.log(this.tasks);
    },
    onXClick: function(e) {
        var task = $(e.currentTarget).parent('li').data('task');
        task.li.remove();
        this.tasks.forEach(function(e,i,a) {
            if(e === task) {
                a.splice(i,1)
            }
        })
    },
    onRemoveClick: function() {
        var that = this; // лишнее
        var oldTasks = that.tasks;
        that.tasks = [];
        oldTasks.forEach(function(e) { // можно использовать bind(this), либо передать конекст 3-им аргументом
            if(e.done) {
                $(e.li).remove(); // ну и опять же, здесь должно быть вызов модели Task
            }else {
                that.tasks.push(e);
            }
        })
    }
};
function Task(li ,name) {
    this.li = li;
    this.name = name;
    this.done = false;
    this.renderTask();
}
Task.prototype = {
    constructor: Task,
    renderTask: function() {
        this.li.html('<input type="checkbox" class="todo-check"> ' +this.name+ '<span class="todo-x"> X </span>');

    },
    edit: function(newName) {
        if(this.done) {
            this.done = false;
            this.li.removeClass('done') // ;
        }
        this.name = newName;
        this.renderTask();
    },
    onCheckChange: function() {
        this.li.toggleClass('done');
        this.done = !this.done;
    }

};
new TodoApp({
    elem: $('.todo') // ;
});


Вторую половину смотрел уже слабо, устал)

Последний раз редактировалось WorM32, 22.08.2014 в 11:23.
Ответить с цитированием