ViewModel中的函数范围

时间:2016-03-15 07:38:41

标签: javascript jquery knockout.js

我正在尝试从Click事件调用我的ViewModel中的函数。当我从foreach循环中调用它时,该函数似乎超出了范围。 JavaScript的新手,并试图围绕如何/为什么被证明是徒劳的。

功能:

$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");
    };
    .
    .
    .

在HTML中,这有效:

<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>

而这不是:

<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>

但是,我显然希望从“单元格”div而不是行调用我的函数。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

一旦您处于另一个foreach循环的范围内,$parent关键字不再引用您认为的对象($root),而是引用Periods } array。

每当您知道您所指的function / property位于根视图模型上时,您应该使用$root代替:

<div class="periodCell"
     data-dyn-bind="click: function(event) { $root.clickedMe(event); }"></div>

答案 1 :(得分:1)

第一个有效,因为范围相同,但在循环中,每个迭代都表示为$data,这可能没有属性clickedMe。您可以尝试使用

$parent.$parent(0).clickedMe(event);

此处$parent将指向初始范围,然后您可以使用$parent(0)转到其父级。

此外,而不是

click: function(event) {$parent(0).clickedMe(event);}

你可以尝试

click: $parent(0).clickedMe

event会自动添加为参数。