Reputation: 505
I am trying to call a function from my ViewModel from a click event. It appears that the function goes out of scope the moment I call it from within a foreach loop. New to JavaScript, and trying to wrap my head around how / why has proved futile.
Function:
$dyn.controls.Test = function (props, element) {
var self = this;
$dyn.ui.Control.apply(this, arguments);
$dyn.ui.applyDefaults(this, props, $dyn.ui.defaults.Test);
self.RowItem = [
{
.
.
.
}];
self.Periods = [
{ Label: "13:00", Open: true },
{ Label: "13:10", Open: true },
.
.
.
{ Label: "14:30", Open: true }];
self.clickedMe = function (action) { //This is the function I want to call
alert("Clicked");
};
.
.
.
In HTML, this works:
<div data-dyn-bind="foreach: $data.RowItem" class="table" id="workspace">
<div class="row">
<div class="resourceCell" data-dyn-bind="attr: {id: $data.Id}">
<div data-dyn-bind="text: $data.Id" class="resourceCell_inner"></div>
</div>
<div class="periodRow" data-dyn-bind="foreach: $parent(0).Periods, click: function(event) {$parent(0).clickedMe(event);}">
<div class="periodCell"></div>
</div>
</div>
</div>
and this does not:
<div data-dyn-bind="foreach: $data.RowItem" class="table" id="workspace">
<div class="row">
<div class="resourceCell" data-dyn-bind="attr: {id: $data.Id}">
<div data-dyn-bind="text: $data.Id" class="resourceCell_inner"></div>
</div>
<div class="periodRow" data-dyn-bind="foreach: $parent(0).Periods">
<div class="periodCell" data-dyn-bind="click: function(event) {$parent(0).clickedMe(event);}"></div>
</div>
</div>
</div>
However, I obviously want my function to be called from the "cell" divs, not the row. Any advice?
Upvotes: 3
Views: 159
Reputation: 24915
First one works because scope is same, but in a loop, every iteration is represented as $data
and this might not have the property clickedMe
. You can try using
$parent.$parent(0).clickedMe(event);
Here $parent
will point to the initial scope and from there you can go to its parent using $parent(0)
.
Also, instead of
click: function(event) {$parent(0).clickedMe(event);}
you can try
click: $parent(0).clickedMe
event
is automatically added as parameter.
Upvotes: 1
Reputation: 49095
Once you're in the scope of another foreach
loop, the $parent
keyword no longer refers to the object you think it is ($root
) but to the Periods
array.
Whenever you know that the function
/ property
you're referring to is on the root view-model, you should use $root
instead:
<div class="periodCell"
data-dyn-bind="click: function(event) { $root.clickedMe(event); }"></div>
Upvotes: 2