开发者

Updating view model from object not working

开发者 https://www.devze.com 2023-01-31 17:43 出处:网络
I want t开发者_JAVA技巧o be able to observe an object inside the view model. I have a simple example that doesn\'t work as expected, can anyone see the problem?

I want t开发者_JAVA技巧o be able to observe an object inside the view model. I have a simple example that doesn't work as expected, can anyone see the problem?

Using knockout 1.1.1, have 2 inputs as such:

<form data-bind="submit: save">
    <input type="text" data-bind="value: deckName" />
    <input type="text" data-bind="value: deck().Name" />
    <button type="submit">Go</button>
</form>

When the page loads, the inputs get the default values, but on submitting the form viewModel.deck().Name is not updated but viewModel.deckName is.

<script type="text/javascript">
    var initialData = {"Name":"test"};

    var viewModel = {
        deck: ko.observable(initialData),
        deckName: initialData.Name,
        save: function() {
            ko.utils.postJson(location.href, { deck: this.deck, deckName: this.deckName });
        }
    };
    ko.applyBindings(viewModel);
</script>

On the form POST, deck will still send "test" no matter the input whilst deckName will be the corresponding input value.

What I really want is to be able to observe an object viewModel.deck and then bind its properties to inputs, but the properties don't get updated.


There are several problems with what you have provided.

  1. You've only set up a one time value setter for your second input since deck().Name is a static value (as opposed to a ko.observable or a ko.observableArray). (To prove this add viewModel.deck({"Name":"updated test"}); to the end of your script after ko.applyBindings(viewModel);)
  2. deckName is a one way binding - it's written during the initial applyBindings and viewModel will be updated by changes made by the user or scripts to the <input>. However, if you make programmatic changes to the viewModel your input field will not be updated to match. You'll want to take a look at the last part of Knockout.js' value binding documentation.

A slightly improved version:

<form data-bind="submit: save">
    <input type="text" data-bind="value: deckName" />
    <input type="text" data-bind="value: deck().Name" />
    <button type="submit">Go</button>
</form>
<script type="text/javascript">
    var initialData = {"Name":"test"};

    var viewModel = {
        deck: ko.observable(initialData),
        // Set up a two way binding
        deckName: ko.observable(initialData.Name),
        // Set up a one time value setter
        save: function() {
            ko.utils.postJson(location.href, ko.toJSON(this));
            // When we save the model we post *it* back, rather than
            // serializing it by hand.
        }
    };
    ko.applyBindings(viewModel);
    viewModel.deck({"Name":"updated test"});
</script>

An alternate version using fromJS:

<form data-bind="submit: save">
    <input type="text" data-bind="value: Name" />
    <button type="submit">Go</button>
</form>
<script type="text/javascript">
    var initialData = {"Name":"test"};

    var viewModel = ko.mapping.fromJS(initialData);
    viewModel.save = function() {
        ko.utils.postJson(location.href, ko.toJSON(this));
        // When we save the model we post *it* back, rather than
        // serializing it by hand.
    }
    ko.applyBindings(viewModel);
</script>

You'll want to look at Knockout's fromJSON and fromJS funcitons (implemented in its mapping plugin).

0

精彩评论

暂无评论...
验证码 换一张
取 消