jQuery TwoWay Data Binding

后端 未结 2 674
长情又很酷
长情又很酷 2021-01-31 04:03

How do you implement a simple two-way data binding in jQuery? Something like knockoutJS, but in the simplest possible form.

Scenario - bind JSON object to table row (eve

2条回答
  •  时光说笑
    2021-01-31 04:39

    My try - HTML

    
    
    
        Data Binding
    
    
        

    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 = $('');
    
            for (var k = 0; k < _fieldListLength; k++) {
                headerRow.append($('', {
                    text: _fieldList[k].toUpperCase()
                }));
            }
            _$table.find('thead').append(headerRow);
    
            for (var i = 0; i < _objectListLength; i++) {
                var objectData = _objectList[i], currentRow = $('');
    
                currentRow.data('source', objectData.element);
                rowList.push(currentRow);
    
                for (var j = 0; j < _fieldListLength; j++) {
                    var field = _fieldList[j], $inputElement = $('', {
                        type: 'text',
                        value: objectData.element[field]
                    });
    
                    $inputElement.data('field', field);
                    objectData.input[field] = $inputElement;
    
                    currentRow.append($('').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

    I've used amazing Watch.JS. How Does Watch.js Work?

    Watch.js now uses Object.observe

    Here is another example Easy Two-Way Data Binding in JavaScript.

    And another question.

    Native JavaScript Data-Binding.

提交回复
热议问题