2015-09-22 42 views
1

我已經實施了簡單的待辦事項清單http://jsfiddle.net/tw9p9sw3/,並添加了可能的添加/刪除待辦事項。如何在Javascript中實現獨立組件?

(function (todoApp) { 
    'use strict'; 

    todoApp.todoItemValue = ''; 

    function _appendListNode() { 
     var listNode = document.createElement('li'); 
     listNode.className = 'list-group-item'; 
     listNode.appendChild(document.createTextNode(todoApp.todoItemValue)); 
     listNode.appendChild(_createRemoveItemButton()); 
     todoList.appendChild(listNode); 
    } 

    function _createRemoveItemButton() { 
     var removeButtonNode = document.createElement('a'), 
      removeButtonLabel = 'Remove'; 

     removeButtonNode.className = 'badge'; 
     removeButtonNode.appendChild(document.createTextNode(removeButtonLabel)); 

     return removeButtonNode; 
    } 

    function _addItem() { 
     todoApp.todoItemValue = document.getElementById('todoInput').value; 
     _appendListNode(); 
     document.getElementById('todoInput').value = ''; 
    } 

    function _removeItem() { 
     var nodeToRemove = this.parentNode; 
     this.parentNode.parentNode.removeChild(nodeToRemove); 
    } 

    function _addEventHandlers() { 
     document.getElementById('todoListForm').addEventListener('submit', function (event) { 
      event.preventDefault(); 
      _addItem(); 
     }); 

     /* 
     * Used delegated event cause todo list is not static, 
     * so we don't need to add events for remove buttons each time after DOM of todo list have changed 
     */ 
     document.getElementById('todoList').addEventListener('click', function (event) { 
      if (event.target && event.target.nodeName === 'A') { 
       event.preventDefault(); 
       _removeItem.call(event.target); 
      } 
     }); 
    } 

    todoApp.init = function() { 
     _addEventHandlers(); 
    }; 

}(window.todoApp = window.todoApp || {})); 

////////////////////////////////////////////////////////// 
// INITIALIZATION 
////////////////////////////////////////////////////////// 
document.onload = todoApp.init(); 

的問題是,如何重新讓這個待辦事項列表作爲獨立的組件,這樣比如我可以在同一頁面上兩次注入/實例化它,應該有待辦事項列表實例之間沒有衝突。

+0

有在Javascript中實現面向對象編程很多教程。 – Barmar

回答

1

基本上你需要創建TodoList類,所以你可以創建這個類的實例,正如在評論中使用OO編程所建議的。

這裏是代碼:

var TodoListComponent = (function() { 
    'use strict'; 

    var todoListTemplate = '<div>' + 
     '<div class="todo-list">' + 
     '<div class="form-container">' + 
     '<form role="form" class="todoListForm">' + 
      '<div class="form-group">' + 
       '<label for="todoInput">Add todo item</label>' + 
       '<input type="text" class="form-control todoInput" required>' + 
      '</div>' + 
      '<button type="submit" class="btn btn-success">Submit</button>' + 
     '</form>' + 
    '</div>' + 
    '<div class="list-container">' + 
     '<ul class="list-group todoList">' + 
      '<li class="list-group-item list-group-item-success">Todo list</li>' + 
     '</ul>' + 
    '</div>' + 
    '</div>' + 
    '</div>'; 

    function TodoList() { 

     this.initialize = function() { 
      this.$el = $(todoListTemplate); 
      this.todoItemValue = ''; 
      this._initEvents(); 
     } 

     this._initEvents = function() { 
      var self = this; 

      this.$el.find('.todoListForm').on('submit', function (event) { 
       event.preventDefault(); 
       self._addItem(); 
      }); 

      /* 
      * Used delegated event cause todo list is not static, 
      * so we don't need to add events for remove buttons each time after DOM of todo list have changed 
      */ 
      this.$el.find('.todoList').on('click', function (event) { 
       if (event.target && event.target.nodeName === 'A') { 
        event.preventDefault(); 
        self._removeItem.call(event.target); 
       } 
      }); 
     } 

     this._appendListNode = function() { 
      var listNode = $('<li>'); 
      listNode.addClass('list-group-item'); 
      listNode.text(this.todoItemValue); 
      listNode.append(this._createRemoveItemButton()); 
      this.$el.find('.todoList').append(listNode); 
     } 

     this._createRemoveItemButton = function() { 
      var removeButtonNode = $('<a>'), 
       removeButtonLabel = 'Remove'; 

      removeButtonNode.addClass('badge'); 
      removeButtonNode.text(removeButtonLabel); 

      return removeButtonNode; 
     } 

     this._addItem = function() { 
      var input = this.$el.find('.todoInput'); 
      this.todoItemValue = input.val(); 
      this._appendListNode(); 
      input.val(''); 
     } 

     this._removeItem = function() { 
      var nodeToRemove = this.parentNode; 
      this.parentNode.parentNode.removeChild(nodeToRemove); 
     } 

     this.render = function() { 
      return this; 
     } 

     this.initialize(); 
    } 

    return TodoList; 
}()); 

////////////////////////////////////////////////////////// 
// INITIALIZATION 
////////////////////////////////////////////////////////// 

var todoList1 = new TodoListComponent(); 
var todoList2 = new TodoListComponent(); 

$('body').append(todoList1.render().$el); 
$('body').append(todoList2.render().$el); 

而且的jsfiddle鏈接:http://jsfiddle.net/tw9p9sw3/10/

這工作,但如果你要使用的數據,地方或者發送物品的東西,那麼你很可能會通過DOM得到它這是糟糕和混亂的。

嘗試使用Backbone,其中DOM僅用於表示,而數據由Javascript保存。

這裏是例子:

http://backbonejs.org/docs/todos.html

+0

謝謝你的例子!我將深入研究這種方法和MV *框架 – sk1llfull