Knockout.js Как поделиться моделью представления, наблюдаемой с компонентом для двухстороннего связывания - PullRequest
0 голосов
/ 30 августа 2018

В этом упрощенном примере я пытаюсь создать единый источник правды для адресов.

vm.companies()[0].address().address1 должен быть наблюдаемым, который совместно используется / подключен к компоненту ввода адреса.

Я, вероятно, использую неправильный шаблон проектирования для того, чего я пытаюсь достичь. В частности, эта часть не работает.

<script type="text/html" id="address-template"> <!-- Address Form Template -->
        <div>
            <input type="text" data-bind="textInput: address1" /> <!-- should bind to company.address().address1() -->
            <input type="text" data-bind="textInput: city" /> <!-- should bind to company.address().city() -->
        </div>
    </script>

При вводе адреса1 / текста города в компоненте ввода адреса следует обновить адрес1 / текст города, отображаемый на странице. Заранее спасибо!

<!DOCTYPE html>
<html>
<head>
    <title>Component Observable</title>
    <script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js"></script>

    <script>
        var vm = '';
        var companyList = [
            { name: 'Microsoft', type: 'Software', address: { address1: '42 Binary Ave', city: 'Seattle' } },
            { name: 'Amazon', type: 'Retail', address: { address1: '1337 Compute Street', city: 'Atlanta' } }
        ];
        var addressVm = function (params) {
            this.address1 = ko.observable(params.address().address1);
            this.city = ko.observable(params.address().city);
        };
        var companyVm = function (params) {
            this.name = ko.observable(params.name);
            this.type = ko.observable(params.type);
            this.address = ko.observable(params.address);
        };
        ko.components.register('address-input', {
            viewModel: addressVm,
            template: { element: 'address-template' }
        });
        window.onload = () => {
            function viewModel() {
                this.init = (Vm) => {
                    $.each(companyList, (i, company) => {
                        cvm = new companyVm(company);
                        this.companies.push(cvm);
                    });
                };
                this.companies = ko.observableArray([]);
                this.init(this);
            }
            vm = new viewModel();
            ko.applyBindings(vm);
        };
    </script>
</head>

<body>

    <script type="text/html" id="address-template"> <!-- Address Form Template -->
        <div>
            <input type="text" data-bind="textInput: address1" /> <!-- should bind to company.address().address1() -->
            <input type="text" data-bind="textInput: city" /> <!-- should bind to company.address().city() -->
        </div>
    </script>

    <div data-bind="foreach: { data: companies, as: 'company' }">
        <div>

            <input type="text" data-bind="textInput: company.name" />
            <div data-bind="text: company.name"></div>

            <input type="text" data-bind="textInput: company.type" />
            <div data-bind="text: company.type"></div>

            <div data-bind="text: company.address().address1"></div>
            <div data-bind="text: company.address().city"></div>

            <address-input params="address: company.address()"></address-input>

        </div>
        <hr />
    </div>

</body>
</html>

1 Ответ

0 голосов
/ 30 августа 2018

Внесение следующих изменений в адреса и модели компании позволяет достичь желаемых результатов.

Удалите декларацию Observable из addressVm view-model и поместите свойства в companyVm.

        var addressVm = function (params) {
            this.address1 = params.address().address1;
            this.city = params.address().city;
        };
        var companyVm = function (params) {
            this.name = ko.observable(params.name);
            this.type = ko.observable(params.type);
            this.address = ko.observable({
                address1: ko.observable(params.address.address1),
                city: ko.observable(params.address.city)
            });
        };

Теперь компонент привязан к тому же наблюдаемому, что и его родитель. Ввод текста в компоненте адреса обновляет текст, отображаемый вне компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...