Reputation: 3238
I got some click binding, that must pass binding context value to the self function for further processing and this value has been passing successfully but function firing on page load instead of click. So, here is ViewModel:
<script src="../Scripts/knockout.mapping-latest.js"></script>
<script>
function UserStatusViewModel() {
var self = this;
self.clients = ko.observableArray();
$.getJSON("/api/users", self.clients);
self.updatestatus = function () {
$.getJSON("/api/users", function (data) {
ko.mapping.fromJS(data, {}, self.clients);
});
}
//Here I'm getting correct data fom click binding context, but this happend on page load, not on click
self.modal = function (un) {
localStorage.clear();
localStorage.setItem("speakto", un);
window.location.replace("http://somehost/operator/dialog");
}
};
$(function () {
var vm = new UserStatusViewModel();
ko.applyBindings(vm, document.getElementById('users'));
var chat = $.connection.chatHub;
chat.client.addChatMessage = function (name, message) {
vm.updatestatus();
};
chat.client.updateStatus = function () {
vm.updatestatus();
}
chat.server.userStatus = function () {
vm.updatestatus();
}
$.connection.hub.start().done(function () {
});
});
</script>
And HTML markup:
<div data-bind="foreach: clients" id="users">
<div class="dialogs">
<div class="speech">
<div class="online">
<img alt="" data-bind="visible: ko.utils.unwrapObservable(IsOnline) == true" src="../img/online.png">
<img alt="" data-bind="visible: ko.utils.unwrapObservable(IsOnline) == false" src="../img/offline.png">
</div>
<div class="ava">
<img alt="" data-bind="attr: { src: ko.utils.unwrapObservable(AvaUrl) }">
</div>
<div class="name" data-bind="text: ko.utils.unwrapObservable(UserName), click: $root.modal(UserName)"></div>
<%--<div class="dateok" data-bind="text: $data.Timer"></div>--%>
<div class="text" data-bind="text: ko.utils.unwrapObservable(LastMessage)"></div>
</div>
</div>
</div>
P.S. Sorry guys, I did changed click binding syntax too fast, current is newest and the one I'm talking about.
Upvotes: 1
Views: 289
Reputation: 7641
let viewModel in JS is defined as:
viewModel = {
clickHandler: function(model, e) { alert(JSON.stringify(model)); }
}
then you can bind it the following way in markup:
data-bind="click: clickHandler"
if you click it, the $data will be passed as "model" argument of the handler
It is described at the knockout docs
Upvotes: 0
Reputation: 139748
Your click binding click: $root.modal(UserName)
is wrong because you are not passing in a function
but the result of the function. So KO will execute your function once when it processes the binding and not when your element is clicked.
You need to use bind
or wrap it into a new function if you want to pass in additional arguments to a click handler:
<div class="name" data-bind="text: ko.utils.unwrapObservable(UserName),
click: $root.modal.bind($data, UserName)"></div>
Or
<div class="name" data-bind="text: ko.utils.unwrapObservable(UserName),
click: function() { $root.modal(UserName) }"></div>
Note: you don't need the ko.utils.unwrapObservable(UserName) in text binding just write text: UserName
However because your UserName
is observable you need to handle it in your modal
function:
self.modal = function (un) {
localStorage.clear();
localStorage.setItem("speakto", ko.utils.unwrapObservable(un));
window.location.replace("http://somehost/operator/dialog");
}
Or make sure that the click binding passes in the value with click: $root.modal.bind($data, ko.utils.unwrapObservable(UserName))
Note: since KO 2.3 there is shorthand for ko.utils.unwrapObservable
and you can just write ko.unwrap
Upvotes: 3