使用Knockout进行复杂的绑定困境

时间:2015-01-27 03:13:56

标签: knockout.js

坦率地说,我不确定我想要做的事情是可能的。仍然...

基本场景是这样的:在foreach:循环中,我正在渲染一个复选框,一个标签和一个下拉列表,如下所示:

<ul data-bind="foreach: $root.ClassDays">
<li>
    <input type="checkbox" data-bind="checkedValue: $data, checked: $root.SCVM.EditingItem().AssignedDates" />
    <label data-bind="text: ClassDay"></label>
    <select data-bind="options: $data.ClassTimes, optionsCaption: 'Select',  value: $root.SCVM.EditingItem().AssignedDates().ClassTime"></select>
</li>

ClassDays对象是一个包含7个AssignedDate个对象的数组,如下所示:

var AssignedDate = function (day) {
    this.AssignedId = 0;
    this.ScheduledClassID = 0;
    this.ClassDay = ko.observable(day || "");
    this.ClassTimes = ko.observableArray(["5:00 PM", "5:30 PM", "6:00 PM", "6:30 PM", "7:00 PM", "7:30 PM", "8:00 PM"])
    this.ClassTime = ko.observable("");
};

ClassDays因此被初始化:

self.ClassDays = [
    new AssignedDate("Monday"),
    new AssignedDate("Tuesday"),
    new AssignedDate("Wednesday"),
    new AssignedDate("Thursday"),
    new AssignedDate("Friday"),
    new AssignedDate("Saturday"),
    new AssignedDate("Sunday")
];

我的目标是在选择“日期”时捕获“时间”值。我当前的实现是在检查框时向AssignedDate添加$root.SCVM.EditingItem().AssignedDates对象,但永远不会设置ClassTime属性。

修改

为了澄清,我的页面的体系结构使用名为SessionsViewModel的视图模型和子视图模型名称\ d ScheduledClassViewModel。子VM名为SCVM。这是父母的(主要)完整的lsiting:

function SessionsViewModel(){
var self = this;
var hasErrors, strMessage, strErrMsg;
self.FailHandler = function (a, b, c) {
    alert(a.responseText);
};
self.MsgGood = ko.observable("");
self.MsgError = ko.observable("");
self.PageMode = ko.observable("");
self.AddSession = function () {
    self.SessionId(null);
    self.CurrentSession(new Session());
    self.PageMode("add");
    self.DetailsVisible(true);
    self.ClassesVisible(false);
};
self.SessionInfoGood = function () {

};
self.DoContinue = function () {
    if (!self.SessionInfoGood()) {
        self.MsgError(strErrMsg);
    }
    else {
        strErrMsg = "";
        self.MsgError("");
        self.ClassesVisible(true);
    }
};
self.DetailsVisible = ko.observable(false);
self.ClassesVisible = ko.observable(false);
self.ToggleDisplay = function () {
    $("#ClassDetails").toggle("blind", {}, 400);        
};
self.Sessions = ko.observableArray();
self.SessionId = ko.observable();
self.SessionId.subscribe(function (newval) {
    if (newval != null && typeof(newval) != "undefined")
    {

    }
});
self.CurrentSession = ko.observable(new Session());
self.GetSessions = function () {

};
self.ClassList = ko.observableArray();
self.CoachList = ko.observableArray();    
self.SCVM = new ScheduledClassViewModel(self);
self.ClassDays = ko.observableArray([
    new AssignedDate("Monday"),
    new AssignedDate("Tuesday"),
    new AssignedDate("Wednesday"),
    new AssignedDate("Thursday"),
    new AssignedDate("Friday"),
    new AssignedDate("Saturday"),
    new AssignedDate("Sunday")
]);
self.AddClass = function () {
    var sc = new ScheduledClass(new BaseClass());
    self.CurrentSession().AssignedClasses.push(sc);
    self.SCVM.SelectClass(sc, "Add");
};

}

这是孩子vm:

var ScheduledClassViewModel = function (parent) {
var self = this;
self.Mode = ko.observable("");
self.ValidationErrorMsg = ko.observable("");
self.ScheduledClass = ko.observable();
self.EditingItem = ko.observable(new ScheduledClass(new BaseClass()));
self.ShouldRemove = ko.observable(false);
self.Validate = function () {
    var isValid = true;

    return isValid;
};
self.Cancelling = ko.observable(false);
self.ClassList = parent.CurrentSession.AssignedClasses;
self.SelectClass = function (classdata, mode) {
    self.Cancelling(true);
    self.Mode(mode);
    self.ScheduledClass(classdata);
    var sc = ko.toJS(classdata);
    self.EditingItem(new ScheduledClass(sc));
    self.ShouldRemove(false);
    self.ValidationErrorMsg("");

};
self.SaveClass = function () {
    if (self.ShouldRemove())
    {
        self.ClassList.remove(self.ScheduledClass())
    }
    else {
        if (self.Validate())
        {
            var selected = self.ScheduledClass(), edited = ko.toJS(self.EditingItem());
            selected.Update(edited);
            self.ClassList.valueHasMutated();
            self.Cancelling(false);
            self.Mode("");
        }

    }
};

};

目标是将选定的ClassDay和ClassTime放入子项内的AssignedDates集合中(在html中标识为$ root.SCVM.EditingItem()。AssignedDates)。虽然supercool提出的解决方案确实有效,但数据最终在父vm而不是子vm中。如果仍然不清楚,请告诉我,我会再试一次。

1 个答案:

答案 0 :(得分:0)

我希望这是你想要的东西。我希望你可以直接使用我的代码并绑定

查看

<div>
    <ul data-bind="foreach: ClassDays">
        <li>
            <input type="checkbox" data-bind="checkedValue:$data, checked:AssignedDates" />
            <label data-bind="text: ClassDay"></label>
            <select data-bind="options: $data.ClassTimes, optionsCaption: 'Select', value:ClassTime"></select>
        </li>
    </ul>
</div>

查看型号:

var ViewModel = function () {
    this.ClassDays = ko.observableArray([
    new AssignedDate("Monday"),
    new AssignedDate("Tuesday"),
    new AssignedDate("Wednesday"),
    new AssignedDate("Thursday"),
    new AssignedDate("Friday"),
    new AssignedDate("Saturday"),
    new AssignedDate("Sunday")]);

}

var AssignedDate = function (day) {
    this.ClassDay = ko.observable(day || "");
    this.ClassTimes = ko.observableArray(["5:00 PM", "5:30 PM", "6:00 PM", "6:30 PM", "7:00 PM", "7:30 PM", "8:00 PM"])
    this.ClassTime = ko.observable("");
    this.AssignedDates = ko.observable(false);
};

工作小提琴 here ,预览更改

如果我失踪了,请告诉我。