Можно ли заставить knockoutjs обновить объект 'initialdata'? - PullRequest
3 голосов
/ 08 февраля 2012

Вот очень упрощенный пример того, что я пытаюсь сделать с knockoutjs:

<!DOCTYPE HTML>
<html>
    <head>
        <title>test</title>
        <script type="text/javascript" src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.debug.js"></script>
        <script type="text/javascript">

            var derp = { "foo": 1, "bar": 2 };

            window.onload = function() { go(); }

            function go()
            {
                var ViewModel = function(foobar)
                {
                    this.foo = ko.observable(foobar.foo);
                    this.bar = ko.observable(foobar.bar);
                }

                ko.applyBindings(new ViewModel(derp));
            }

        </script>
    </head>
    <body>
        <input data-bind="value: foo"/>
        <input data-bind="value: bar"/>
        <button onclick="go();">Go</button>
    </body>
</html>

Цель этого кода - иметь knockoutjs для обновления значений в derp, а не копию внутри ViewModel.

Есть ли способ сделать это легко нокаутом, или я лаю не на том дереве?

Изменить для контекста:

Это взято из гораздо большего приложения. Моим намерением было использовать knockout для отображения и редактирования свойств большого шерстяного объекта javascript. Эти объекты создаются пользователем динамически и могут переключаться между ними по желанию.

Прежде чем я обнаружил найденный нокаут, мне вручную создавали элементы DOM для отображения и редактирования каждого объекта, который был грязным и громоздким. У меня есть некоторый опыт работы с MVVM через WPF в C #, и я бы предпочел использовать этот подход. Мое первоначальное понимание нокаута состояло в том, что он будет делать это, не понимая, что ViewModel копирует значения, захваченные ko.observable*. ViewModel все еще используется для меня, поскольку позволяет мне условно предоставлять и упрощать доступ к членам, которые я хочу редактировать.

Ответы [ 2 ]

3 голосов
/ 09 февраля 2012

Мне нравится ответ @Etch методом Save. Это очень помогает. Но если Вы хотите автоматизировать такие вещи, то я бы пошел с subscribe на наблюдаемые.

Может быть, это не более чистый способ сделать это. Я был бы счастлив, если бы смог передать переменную по ссылке.

Я предпочитаю использовать какую-то обертку вокруг наблюдаемых, чтобы набирать меньше:

var returnFireObservable = function(variable, property) {
    var obs = ko.observable(variable[property]);
    obs.subscribe(function(newValue) {
        variable[property] = newValue;
    });
    return obs;
};

И использовать в коде так:

var ViewModel = function(foobar) {
    this.foo = returnFireObservable (foobar, "foo");
    this.bar = returnFireObservable (foobar, "bar");
};

ko.applyBindings(new ViewModel(derp));

Маленькая демонстрация http://jsfiddle.net/AlfeG/eQ9Zf/2/

Надеюсь, это поможет.

1 голос
/ 09 февраля 2012

Я не уверен на 100%, что я полностью понимаю, что вы хотите, но я сделаю это.

Вы определили свою модель так:

var ViewModel = function(foobar)
            {
                this.foo = ko.observable(foobar.foo);
                this.bar = ko.observable(foobar.bar);
            }

вы инициализировали свою нокаут-модель с var derp = { "foo": 1, "bar": 2 }; намного более сложным объектом.

Таким образом, ваши входные данные получат эти значения благодаря тегу data-bind. Затем вы изменяете эти входные значения, затем нажимаете кнопку сохранения и хотите обновить исходный объект javascript.

Если бы это было так, я бы склонялся к этому ...

Измените вашу модель представления на эту:

var ViewModel = function(foobar)
                {

                    this.foo = ko.observable(foobar.foo);
                    this.bar = ko.observable(foobar.bar);
                    save: function() { derp.foo = this.foo;
                                       derp.bar = this.bar;          
                        //  ko.utils.postJson(location.href, { obj1: this.foo, obj2: this.bar });
                    }
                }

А затем измените событие нажатия кнопки на: ViewModel.save();

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

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