binding with 'with'?
In Knockout documentation, it's said that one-way data-binding is possible if we do NOT use ko.observable(...): http://knockoutjs.com/documentation/value-binding.html
However, this following code doesn't work as I expect:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form data-bind="with: selectedMerchant">
<input data-bind="value: name"></input>
<button data-bind="click: change"> CHANGE </button>
<button data-bind="click: show"> SHOW </button>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js" type="text/javascript"></script>
<script>
function PartnersViewModel() {
self.selectedMerchant = {'name': 'John'};
self.show = function() {
alert(JSON.stringify(self.selectedMerchant));
}
self.change = function() {
self.selectedMerchant = {'name': 'David'};
}
}
ko.applyBindings(new PartnersViewModel());
</script>
</body>
</html>
'selectedMerchant' is declared without ko.observable(...), so it's supposed to be one-way binded. I expect that once I click the 'CHANGE' button, the text inside the input box will change to be 'David'. I also tried the different direction - I changed the text inside the input and clicked 'SHOW' button. The message box gave the initial value it had at the beginning.
If you want a true one-way binding that will continue to update the UI you can use a computed observable. Unless you specify a "write" property for the computed it will only update in the model->UI direction. That being said you can achieve the same result by just replacing your input box with a span or label to prevent the user from updating the value, so I'm not sure I see the utility of a one-way binding.
function PartnersViewModel() {
var self = this;
self.selectedMerchant = ko.observable({'name': 'John'});
self.show = function() {
alert(JSON.stringify(self.selectedMerchant()));
}
self.change = function() {
self.selectedMerchant({'name': 'David'});
}
self.selectedName = ko.computed(function(){
return self.selectedMerchant().name;
});
}
ko.applyBindings(new PartnersViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js" type="text/javascript"></script>
<div data-bind="with: selectedMerchant">
<input data-bind="value: $parent.selectedName"></input>
<button data-bind="click: $parent.change"> CHANGE </button>
<button data-bind="click: $parent.show"> SHOW </button>
</div>
To expand on M. Ihsan's correct answer, Knockout will bind one way when not using observables, and using normal JavaScript variables/objects. Here is an example.
function ExampleObject(one, two) {
var self = this;
self.one = one;
self.two = ko.observable(two);
self.ChangeVariables = function() {
self.one = "1";
self.two("2");
console.log(self.one, ko.toJS(self.two));
}
}
function ViewModel() {
var self = this;
self.bindingExample = ko.observableArray();
self.Load = function() {
self.bindingExample.push(new ExampleObject("one way", "two ways"));
self.bindingExample.push(new ExampleObject("one way", "two ways"));
self.bindingExample.push(new ExampleObject("one way", "two ways"));
self.bindingExample.push(new ExampleObject("one way", "two ways"));
}
self.Load();
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<table border=1>
<thead>
<tr>
<th>1 way</th>
<th>2 way</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: bindingExample">
<tr>
<td data-bind="text: one"></td>
<td data-bind="text: two"></td>
<td> <a data-bind="click: ChangeVariables"> Change Variables</a></td>
</tr>
</tbody>
</table>
The with
binding is already a one-way binding, as are most bindings. They're one-way from the model to the view, but this requires the model value to be an observable.
value
is normally a two-way binding. The one-way nature described in the documentation is from view to model, which isn't the direction you want anyway.
In other words, you need selectedMerchant
to be observable.
上一篇: 用MySQL计算中位数的简单方法
下一篇: 与'与'绑定?