Reputation: 179
I'm struggling with issues from KnockoutJS, I have block code below
var viewModel = function (value){
this.name = ko.observable(value);
}
var model = {}; model.firstName = "ABC";
var AppViewModel = new viewModel(model.firstName);
ko.applyBindings(AppViewModel);
And in HTML i have a view with binding
data-bind="textInput: name".
It's good work. TextView display with text: "ABC". I have a question. when I change value in TextView. Whether if that model (special firstName) update new value from textView ?
Upvotes: 0
Views: 44
Reputation: 884
The problem is that model.firstName
is an object property
but it isn't an observable
, instead you're using that object property
to set the observable
, the observable
is the two way binding, if you want firstName
to be an observable/two way binding you can do it like so:
var viewModel = function (){
VM = this;
VM.firstName = ko.observable("ABC");
return VM;
}
var AppViewModel = new viewModel();
ko.applyBindings(AppViewModel);
Here we're creating a function viewModel()
that returns an object
with the property firstName
which is a knockout observable containing "ABC"
. Then we're creating an instance of that view model and applying it to the page. Now if you make any changes in the input it should update the value of AppViewModel.firstName
.
Or to keep it more similar to your code you can do it like this:
var viewModel = function (){
this.firstName = ko.observable("ABC");
}
var AppViewModel = new viewModel();
ko.applyBindings(AppViewModel);
Note that there is no need to create the model
object with the property firstName
, you can just initialise the observable
with a string
and it will pick up any changes made in the textInput
binding.
Upvotes: 1
Reputation: 63840
Your constructor function AppViewModel
takes in the Model upon construction. The resulting ViewModel will be two-way data-bound to the view.
What you'd typically have is a reverse method to the constructor, that can be used e.g. when saving the changes through a Model in a back-end. Here's a demo with your example:
function AppViewModel(model){
var self = this;
self.firstName = ko.observable(model.firstName);
self.lastName = ko.observable(model.lastName);
self.asModel = ko.computed(function() {
return {
firstName: self.firstName(),
lastName: self.lastName()
};
});
self.saveInBackend = function() {
// Typically you'd ajax here, instead we log the model:
console.log(self.asModel());
};
}
var model = {};
model.firstName = "John";
model.lastName = "Doe";
var viewModel = new AppViewModel(model);
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Firstname: <input data-bind="textInput: firstName"><br>
Lastname: <input data-bind="textInput: lastName"><br>
<button data-bind="click: saveInBackend">saveInBackend</button>
<h4>Debug info, this is the state of your *view model*:</h4>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
<h4>Debug info, this is the state of an updated model:</h4>
<pre data-bind="text: ko.toJSON($root.asModel(), null, 2)"></pre>
<h4>Debug info, this is the state of your *initial model* (which doesn't change):</h4>
<pre data-bind="text: ko.toJSON(window.model, null, 2)"></pre>
Upvotes: 0