jQuery 双向数据绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15309910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 14:47:58  来源:igfitidea点击:

jQuery TwoWay Data Binding

javascriptjquerydata-binding

提问by kayz1

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

你如何在 jQuery 中实现一个简单的双向数据绑定?类似于knockoutJS,但采用最简单的形式。

Scenario - bind JSON object to table row (every field is td>input/>/td>).

场景 - 将 JSON 对象绑定到表行(每个字段都是td>input/>/td>)。

Any suggestions?

有什么建议?

采纳答案by kayz1

My try - HTML

我的尝试 - 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

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

结果

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

我使用了惊人的Watch.JSWatch.js 是如何工作的?

Watch.js now uses Object.observe

Watch.js 现在使用 Object.observe

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

这是JavaScript 中的 Easy Two-Way Data Binding 的另一个示例。

And another question.

还有一个问题。

Native JavaScript Data-Binding.

原生 JavaScript 数据绑定

回答by Kaszoni Ferencz

This solution is pretty simple, and it can be extended to have a more complex functionality: http://cssshowcase.co.uk/two-way-data-binding-with-jquery/

这个解决方案非常简单,它可以扩展为具有更复杂的功能:http: //cssshowcase.co.uk/two-way-data-binding-with-jquery/

It literally binds 2 or more HTML elements together, with it's current form it changes the inner html of any element and the value of any input as well, for each element that holds the same "bind" attribute value.

它实际上将 2 个或更多 HTML 元素绑定在一起,以它的当前形式更改任何元素的内部 html 以及任何输入的值,对于每个具有相同“绑定”属性值的元素。