admin管理员组文章数量:1431398
I'm a little puzzled by some code I plunked together that doesn't behave quite as I'd expect.
I'm sure I'm doing something wrong (and given the late hour here, it might be something simple), but I'm looking for some clarity on why this happens.
I'm using:
- jQuery 1.10.2
- Knockout 2.3.0
- Bootstrap 3.0.3
The Problem
- I define a function in my ViewModel, which sets an observable to a certain value.
- This is not called from anywhere else in my code.
- I define a
data-bind="click: AddAnnouncement"
binding on a button that's part of a button group. - When
ko.applyBindings(vm)
is called, theAddAnnouncement
function fires, giving me an undesired result long before I click on anything.
The Code in Question
Can be found in a JSFiddle at: /.
Essentially, I have the following JavaScript code:
var MyNamespace = MyNamespace || {
ViewModel: function(){
'use strict';
var self = this;
self.AddingAnnouncement = ko.observable(false);
self.AddAnnouncement = function(){
self.AddingAnnouncement(true);
};
self.Start = function(){
self.AddingAnnouncement(false);
};
self.Start();
}
};
var vm;
$(document).ready(function(){
'use strict';
vm = new MyNamespace.ViewModel();
ko.applyBindings(vm);
//do something with jQuery? Bind a VM?
});
My binding code is also pretty elementary (I thought):
<div class="container">
<div class="row">
<div class="btn-group">
<button type="button" class="btn btn-default"><abbr Title="Announcement" data-bind="click: AddAnnouncement()">A</abbr>
</button>
</div>
</div>
<div class="row" data-bind="visible: AddingAnnouncement() == true">
<h1>Add a new announcement</h1>
</div>
</div>
What I think it's doing
I think the code in question is doing the following:
- Defining a namespace called
MyNamespace
(albeit probably not in the best way; this may be part of the problem?) - Defining a
ViewModel
object inside the namespace - Giving the
ViewModel
object an observable calledAddingAnnouncment
and a function calledAddAnnouncement
, which setsAddingAnnouncement
to true. - Defines a
Start
method which ensures thatAddingAnnouncement
is set to false by default; - Calls the
Start
method as the last step in its initialization.
What am I Missing Here?
I think I'm not grasping some standard behavior of JavaScript or something about the way knockout binds models, but it seems like when applying the bindings, knockout executes all of the functions, even for the click bindings. However, that doesn't make sense to me and so I'm betting I'm wrong.
Someone enlighten me? Thanks!
I'm a little puzzled by some code I plunked together that doesn't behave quite as I'd expect.
I'm sure I'm doing something wrong (and given the late hour here, it might be something simple), but I'm looking for some clarity on why this happens.
I'm using:
- jQuery 1.10.2
- Knockout 2.3.0
- Bootstrap 3.0.3
The Problem
- I define a function in my ViewModel, which sets an observable to a certain value.
- This is not called from anywhere else in my code.
- I define a
data-bind="click: AddAnnouncement"
binding on a button that's part of a button group. - When
ko.applyBindings(vm)
is called, theAddAnnouncement
function fires, giving me an undesired result long before I click on anything.
The Code in Question
Can be found in a JSFiddle at: http://jsfiddle/SeanKilleen/v8ReS/.
Essentially, I have the following JavaScript code:
var MyNamespace = MyNamespace || {
ViewModel: function(){
'use strict';
var self = this;
self.AddingAnnouncement = ko.observable(false);
self.AddAnnouncement = function(){
self.AddingAnnouncement(true);
};
self.Start = function(){
self.AddingAnnouncement(false);
};
self.Start();
}
};
var vm;
$(document).ready(function(){
'use strict';
vm = new MyNamespace.ViewModel();
ko.applyBindings(vm);
//do something with jQuery? Bind a VM?
});
My binding code is also pretty elementary (I thought):
<div class="container">
<div class="row">
<div class="btn-group">
<button type="button" class="btn btn-default"><abbr Title="Announcement" data-bind="click: AddAnnouncement()">A</abbr>
</button>
</div>
</div>
<div class="row" data-bind="visible: AddingAnnouncement() == true">
<h1>Add a new announcement</h1>
</div>
</div>
What I think it's doing
I think the code in question is doing the following:
- Defining a namespace called
MyNamespace
(albeit probably not in the best way; this may be part of the problem?) - Defining a
ViewModel
object inside the namespace - Giving the
ViewModel
object an observable calledAddingAnnouncment
and a function calledAddAnnouncement
, which setsAddingAnnouncement
to true. - Defines a
Start
method which ensures thatAddingAnnouncement
is set to false by default; - Calls the
Start
method as the last step in its initialization.
What am I Missing Here?
I think I'm not grasping some standard behavior of JavaScript or something about the way knockout binds models, but it seems like when applying the bindings, knockout executes all of the functions, even for the click bindings. However, that doesn't make sense to me and so I'm betting I'm wrong.
Someone enlighten me? Thanks!
Share Improve this question asked Dec 9, 2013 at 5:59 SeanKilleenSeanKilleen 8,97718 gold badges85 silver badges139 bronze badges2 Answers
Reset to default 6Whooops! The answer to that question turned out to be right under my nose; indeed, all I had to do was write that entire darn question before I saw it. :)
The problem is with my binding:
<button type="button" class="btn btn-default"><abbr Title="Announcement" data-bind="click: AddAnnouncement()">A</abbr>
Note a very important distinction: AddAnnouncement()
. The ()
matters quite a bit in this case.
When knockout assigns its binding, it does so by directly referencing what you enter. Since I entered AddAnnouncement()
, it assigned the binding to the output of the function that had been run once, rather than the function itself which would be executed at a later time.
The best way to do it would have been to use AddAnnouncment
, without paranetheses, like this:
<button type="button" class="btn btn-default"><abbr Title="Announcement" data-bind="click: AddAnnouncement">A</abbr>
This does not execute the function upon applying bindings.
While I forgot to avoid such a simple mistake, I hope it saves someone else time in the future. The working JSFiddle can be found at http://jsfiddle/SeanKilleen/v8ReS/4/.
We usually confuse when to use parentheses () when we bind View with ViewModel.
As when you bind AddAnnouncement
function, you directly bind with function call like AddAnnouncement()
. That why the AddAnnouncement
function call when you bind using ko.applyBindings
even though we didn't click the button, the function call already fire.
<div class="row">
<div class="btn-group">
<button type="button" class="btn btn-default">
<abbr Title="Announcement" data-bind="click: AddAnnouncement()">
A
</abbr>
</button>
</div>
</div>
so we change as below
<div class="row">
<div class="btn-group">
<button type="button" class="btn btn-default">
<abbr Title="Announcement" data-bind="click: AddAnnouncement">
A
</abbr>
</button>
</div>
</div>
working jsfiddle
本文标签: javascriptKnockoutJS How to avoid running a viewmodel function on applyBindingsStack Overflow
版权声明:本文标题:javascript - KnockoutJS: How to avoid running a viewmodel function on applyBindings? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745576112a2664337.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论