无法访问内部循环中的knockout方法

时间:2013-11-27 13:31:25

标签: knockout.js knockout-2.0

我有一个像这样的父模型

function VM() {
    var self = this;
    self.MyPage =   ko.observable()

}   

var vm = new VM()

然后我有这样的儿童模特。

var page = function(parent) {
    var self    = this
    self.Info   =   ko.observable()

    self.LoadData   =   function(){
        self.GetNext()
    }

    self.GetNext = function(){
        var url     =   'Questions/GetNext'
        var type    =   'GET'
        ajax(url , null , self.OnGetNextComplete, type )                    
    }
    self.OnGetNextComplete = function(data){
        self.Info(data.Payload)
    }


    self.AcceptedChoices = function(data,choiceId){
        return in_array(choiceId,data.AcceptedChoices) ? 'selected' : ''
    }
    self.LoadData()
}

以下是我如何使用它。

vm.MyPage(new page(vm))
ko.applyBindings(vm)            

目前一切正常。现在要在页面上使用这个孩子,我就像这样使用with binding

`<body data-bind="with:MyPage">`

这让我可以在当前页面上使用child。 接下来我就像这样绑定。

<div data-bind="foreach:Info">
    <article>
        <h2 data-bind="text:QuestionText"></h2>
        <ul data-bind="foreach:Choices">
            <li data-bind="text:ChoiceText,css:$parent.AcceptedChoices()"></li>
        </ul>
    </article>
</div>

这是信息json

{
    "Choices": [{
        "ChoiceId": 102,
        "ChoiceText": "Not at all"
    }, {
        "ChoiceId": 103,
        "ChoiceText": "Somewhat"
    }, {
        "ChoiceId": 104,
        "ChoiceText": "Very important"
    }],
    "QuestionText": "My personal religious beliefs are important"
},{
    "Choices": [{
        "ChoiceId": 99,
        "ChoiceText": "Never"
    }, {
        "ChoiceId": 100,
        "ChoiceText": "Sometimes"
    }, {
        "ChoiceId": 101,
        "ChoiceText": "Always"
    }],
    "QuestionText": "I am a leader"
}, 
{
    "Choices": [{
        "ChoiceId": 96,
        "ChoiceText": "Never"
    }, {
        "ChoiceId": 97,
        "ChoiceText": "Sometimes"
    }, {
        "ChoiceId": 98,
        "ChoiceText": "Always"
    }],
    "QuestionText": "I manage time properly"
}

问题在于它总是说$parent.AcceptedChoices未定义。我使用过root , parent[1] , parent[2]等但没有任何效果。我怎么能这样做。

1 个答案:

答案 0 :(得分:0)

当您实例化新的视图模型时,它不会明确地将您要查找的关系从子项创建回父项。在现有上下文中创建新上下文时,将创建子项的$ parent。这是在你做这样的事情时完成的 -

// Context of myPage
<div data-bind="with: myPage">
    // Each instance of Info creates it's own context
    <div data-bind="foreach:Info">
        // Now you can reference the $parent object, whi
        <article data-bind="with: $parent.selectedInfo">
        </article>
        // Or you can reference the parent's parent, which has myPage within it's context
        <article data-bind="with: $parents[1].myPage">
        </article>
    </div>
</div>

因为上下文在它自己的范围内创建了一个新的上下文。

您正在做的是引用具有自己的上下文的单独视图模型。要访问父视图模型,您可以执行以下操作 -

var page = function(parent) {
    var self = this;
    self.Info = ko.observable();
    self.parentVM = parent;
}

在此上下文中定义父项的位置应该引用要传入的父视图模型。然后您可以从视图模型中调用它 -

<div data-bind="with: parentVM.myPage"></div>

当然这是伪代码,所以你可能需要调整它以达到你想要的效果。