SB2055
SB2055

Reputation: 12912

Why is this knockout function being executed?

In my view:

<!-- ko if: !isEditingAboutMe() -->
<p data-bind="text: aboutMe()">@Model.AboutMe</p>
@if (Model.CurrentUserCanEdit)
{
    <a data-bind="click: editAboutMe">edit</a>
}
<!-- /ko -->
<!-- ko if: isEditingAboutMe() -->
@Html.TextBoxFor(model => model.AboutMe, new { data_bind = "value: aboutMe" })
<a data-bind="click: saveAboutMe(userId)">save</a>
<a data-bind="click: cancelAboutMe">cancel</a>
<!-- /ko -->

<script type="text/javascript">
$(document).ready(ko.applyBindings(new ProfileVm(@Html.Raw(Json.Encode(Model)))));
var userId = @Html.Raw(Json.Encode(User.Identity.Name));
</script>

My viewModel:

function ProfileVm(model) {
var self = this;

self.aboutMe = ko.observable(model.AboutMe);

self.saveAboutMe = function (username) {
    dataservice().updateAboutMe(username, self.aboutMe());
    self.isEditingAboutMe(false);
};

self.cancelAboutMe = function() {
    self.isEditingAboutMe(false);
};

self.isEditingAboutMe = ko.observable(false);
self.editAboutMe = function() {
    self.isEditingAboutMe(true);
};
}

When I click "edit", the DOM changes as I'd expect, but saveAboutMe is executed. It should only be executed if I click 'save', hence the click: binding. What's going on?

Upvotes: 2

Views: 91

Answers (1)

Rob Alarcon
Rob Alarcon

Reputation: 1450

You're executing the function when you open and close the parenthesis "saveAboutMe(userId)", you just need to set the name of the function "saveAboutMe" on the click binding.

  1. Remove the "(userId)" from your function call
  2. In the function definition "saveAboutMe"
  3. You can use "userId" in your function because its global.

What you can do to make this a little bit cleaner if you wish is to pass in the global variable to your "save" function.

userId = @Html.Raw(Json.Encode(User.Identity.Name));

And in your click binding:

<a data-bind="click: function(){saveAboutMe(userId);}">save</a>

What you had been doing here is to define an anonymous function that will call "saveAboutMe" when the user click the "save" anchor. The difference between this and what you are doing is that here, the anonymous function is just defined, not executed.

another cleaner thing is to add the userId to your ko ViewModel and just make a reference to it in the function:

self.saveAboutMe = function (username) {
    console.log(self.userId); // this should work if you add your userId to your view model.
    dataservice().updateAboutMe(username, self.aboutMe());
    self.isEditingAboutMe(false);
};

Upvotes: 2

Related Questions