jQuery双向数据绑定

问题描述:

如何在jQuery中实现简单的双向数据绑定? 类似knockoutJS,但以最简单的形式。场景 - 将JSON对象绑定到表格行(每个字段为td> input />/td>)。jQuery双向数据绑定

有什么建议吗?

+2

你应该给一个更具体的例子和一些尝试。 – soyuka 2013-03-09 11:00:15

+1

我做到了。检查我自己的答案。任何建议,诡计? – kayz1 2013-03-09 17:10:27

+0

http://jquerymy.com/ – 2015-09-03 20:59:58

我尝试 - HTML

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Data Binding</title> 
</head> 
<body> 
    <table id="content-table"> 
     <thead> 
     </thead> 
     <tbody></tbody> 
    </table> 
    <button id="get-data">Get</button> 
    <button id="set-data">Set</button> 

    <script src="../js/vendor/jquery-1.9.1.js"></script> 
    <script src="../js/vendor/jquery-migrate-1.1.1.js"></script> 
    <script src="../js/vendor/watch.js"></script> 
    <script src="../js/dataBinder.js"></script> 
</body> 
</html> 

的JavaScript

var DataBinder = (function ($) { 

    var _$table = null, 
     _objectList = [], 
     _fieldList = [], 
     _objectListLength = -1, 
     _fieldListLength = -1; 

    /* AJAX call or smth. */ 
    var _loadData = function() { 
     var fakeData = [{ 
      name: 'John', 
      surname: 'Doe' 
     }, { 
      name: 'Foo', 
      surname: 'Bar' 
     }]; 

     _objectList = $.map(fakeData, function (element, index) { 
      var elementObject = { 
       _dataBinderId: index, 
       element: element, 
       input: {} 
      }; 

      watch(elementObject.element, function (property, action, newValue) { 
       _setValue.call(elementObject, property, newValue); 
      }); 

      return elementObject; 
     }); 

     _objectListLength = _objectList.length; 
    }; 

    var _getFields = function() { 
     for (var i = 0; i < _objectListLength; i++) { 
      for (var field in _objectList[i].element) { 
       if (!!!~$.inArray(field, _fieldList)) { 
        _fieldList.push(field); 
       } 
      } 
     } 

     _fieldListLength = _fieldList.length; 
    }; 

    var _setValue = function (field, value) { 
     this.input[field].val(value); 
    }; 

    var _bindEvents = function() { 
     $('#get-data').on('click', function() { 
      alert(JSON.stringify(_getRowData())); 
     }); 

     $('#set-data').on('click', function() { 
      _objectList[0].element.name = 'PIPA'; 
      _objectList[1].element.surname = 'BLAAAAAAH'; 
     }); 

     _$table.on('keyup', 'input', function() { 
      var $this = $(this), field = $this.data('field'), source = $this.closest('tr').data('source'); 
      source[field] = $this.val(); 
     }); 
    }; 

    var _getRowData = function() { 
     var elements = []; 

     $.each(_objectList, function() { 
      elements.push(this.element); 
     }); 

     return elements; 
    }; 

    var _generateEditableElements = function() { 
     var rowList = [], headerRow = $('<tr>'); 

     for (var k = 0; k < _fieldListLength; k++) { 
      headerRow.append($('<th>', { 
       text: _fieldList[k].toUpperCase() 
      })); 
     } 
     _$table.find('thead').append(headerRow); 

     for (var i = 0; i < _objectListLength; i++) { 
      var objectData = _objectList[i], currentRow = $('<tr>'); 

      currentRow.data('source', objectData.element); 
      rowList.push(currentRow); 

      for (var j = 0; j < _fieldListLength; j++) { 
       var field = _fieldList[j], $inputElement = $('<input>', { 
        type: 'text', 
        value: objectData.element[field] 
       }); 

       $inputElement.data('field', field); 
       objectData.input[field] = $inputElement; 

       currentRow.append($('<td>').append($inputElement)); 
      } 
     } 

     _$table.find('tbody').append(rowList); 
    }; 

    var init = function ($table) { 
     _$table = $table; 

     _loadData(); 
     _getFields(); 

     _generateEditableElements(); 
     _bindEvents(); 
    }; 

    return { 
     init: init 
    }; 

})(jQuery); 

DataBinder.init($("#content-table")); 

Result

我用惊人Watch.JSHow Does Watch.js Work?

Watch.js now uses Object.observe

下面是另一个例子Easy Two-Way Data Binding in JavaScript

而另一question.

Native JavaScript Data-Binding

+2

Watch.JS看起来不错,但它使用setInterval进行定期检查。这对性能来说不是很好... – 2013-12-06 23:41:51

+2

现在它使用Object.observe(如果存在)。 – kayz1 2014-08-29 17:12:16

+0

太棒了!我期待着根据这个新功能测试Watch.js! – 2014-08-30 20:32:28

该解决方案是相当简单的,它可以扩展到具有更复杂的功能性:http://cssshowcase.co.uk/two-way-data-binding-with-jquery/

它的字面结合2个或更多的HTML元素一起,与它的它改变任何元件的内HTML目前的形式和任何输入的值也适用于每个拥有相同“绑定”属性值的元素。