Javascript 在嵌套的ObservalArray(knockout.js)中调用函数

Javascript 在嵌套的ObservalArray(knockout.js)中调用函数,javascript,knockout.js,Javascript,Knockout.js,我有一个视图模型,其中有几个嵌套的ObservableArray,我需要调用一个函数来从其中一个数组中删除项。我将尝试用英语描述模型,而不是用图表(代码中也包含了该模型)。视图模型是一个训练计划,它有一个可观察的星期对象。除其他属性外,每个星期对象都有一个天对象的observableArray。除其他属性外,每个day对象都有一组可观察的训练对象。除其他属性外,每个训练对象都有一组可观察的间隔对象。我是一个新手,在javascript方面还不是很稳定(因此可能在这里做了一些错误的事情,请随意批评

我有一个视图模型,其中有几个嵌套的ObservableArray,我需要调用一个函数来从其中一个数组中删除项。我将尝试用英语描述模型,而不是用图表(代码中也包含了该模型)。视图模型是一个训练计划,它有一个可观察的星期对象。除其他属性外,每个星期对象都有一个天对象的observableArray。除其他属性外,每个day对象都有一组可观察的训练对象。除其他属性外,每个训练对象都有一组可观察的间隔对象。我是一个新手,在javascript方面还不是很稳定(因此可能在这里做了一些错误的事情,请随意批评)。问题在于Day对象上的removeWorkout功能。下面是淘汰赛网站上的示例2:。我想我是在按照页面上说的做,但是当我检查函数中的“this”时,调用函数的是Day对象,而不是Workout对象。我哪里做错了

我的javascript文件:

  $(document).ready(function() {  
        var trainingPlan;
        var weekNumber = 0;
        var workoutNumber = 0;    
        var planID = { id: $('#ID').val() };

        $.getJSON('/PlanBuilder/GetPlanJson', planID, function (model) {
        trainingPlan = ko.mapping.fromJSON(model.Message);

        trainingPlan.addWeek = function() {
            var wk = new week();

            weekNumber++;
            wk.Name = 'Week ' + weekNumber;

            for (var i = 1; i < 8; i++) {
                var dy = new day();
                dy.DayNumber = i;
                wk.Days.push(dy);
            }

            var summ = new day();
            summ.DayNumber = "Summary";
            wk.Days.push(summ);

            this.Schedule.push(wk);
        };

        ko.applyBindings(trainingPlan);
    });

    function week() {
        this.PlanID = ko.observable();
        this.StartDate = ko.observable();
        this.EndDate = ko.observable();
        this.Name = ko.observable();
        this.Days = ko.observableArray(); // a list of day objects
    };

    function day() {
        var self = this;

        self.DayNumber = ko.observable();
        self.TodaysDate = ko.observable();
        self.Name = ko.observable();
        self.Workouts = ko.observableArray(); // a list of workout objects
        self.addWorkout = function () {
            var wrk = new workout();
            wrk.Type = "Workout " + workoutNumber++;
            self.Workouts.push(wrk);
        };
        self.removeWorkout = function () {
            // 'this' should represent the item that originated the call (a workout)  Not the case...
            self.Workouts.remove(this);
        };
    };

    function workout() {
        this.Type = ko.observable(); //need to figure out what/how to handle enums
        this.WarmUp = ko.observableArray(); // a list of intervals
        this.Main = ko.observableArray(); // a list of intervals
        this.CoolDown = ko.observableArray(); // a list of intervals
        this.Status = ko.observable();
        this.Completed = ko.observable();
    };

    function interval() {
        this.timeValue = ko.observable();
        this.timeUnit = ko.observable();
        this.rpeUnits = ko.observable();
        this.heartRateZone = ko.observable();
        this.description = ko.observable();
        this.distanceValue = ko.observable();
        this.distanceUnit = ko.observable();
    };
});
$(文档).ready(函数(){
var培训计划;
变量weekNumber=0;
var值=0;
var planID={id:$('#id').val();
$.getJSON('/PlanBuilder/GetPlanJson',planID,函数(模型){
trainingPlan=ko.mapping.fromJSON(model.Message);
trainingPlan.addWeek=函数(){
var wk=新的一周();
weekNumber++;
wk.Name='周'+周数;
对于(变量i=1;i<8;i++){
var dy=新的一天();
dy.DayNumber=i;
工作日推送(dy);
}
var sum=新的一天();
summ.DayNumber=“Summary”;
工作日推送(总和);
本.时间表.推送(wk);
};
ko.应用绑定(培训计划);
});
功能周(){
this.PlanID=ko.observable();
this.StartDate=ko.observable();
this.EndDate=ko.observable();
this.Name=ko.observable();
this.Days=ko.observableArray();//日期对象的列表
};
功能日{
var self=这个;
self.DayNumber=ko.observable();
self.TodaysDate=ko.observable();
self.Name=ko.observable();
self.Workouts=ko.observearray();//训练对象列表
self.addWorkout=函数(){
var wrk=新训练();
wrk.Type=“Workout”+workoutNumber++;
自我锻炼推(wrk);
};
self.remove锻炼=功能(){
//“this”应表示发起呼叫(训练)的项目,而不是案例。。。
自我。锻炼。移除(此);
};
};
功能锻炼(){
this.Type=ko.observable();//需要弄清楚如何处理枚举
this.WarmUp=ko.observearray();//间隔列表
this.Main=ko.observearray();//间隔列表
this.CoolDown=ko.observearray();//间隔列表
this.Status=ko.observable();
this.Completed=ko.observable();
};
函数间隔(){
this.timeValue=ko.observable();
this.timeUnit=ko.observable();
this.rpeUnits=ko.observable();
this.heartRateZone=ko.observable();
this.description=ko.observable();
this.distanceValue=ko.observable();
this.distanceUnit=ko.observable();
};
});
我的看法是:

<div class="container">
    <div class="page-header">
        <h2>@ViewBag.HeaderText</h2>
    </div>

    <div class="panel panel-default">
        <div class="panel-heading">
            <h3>Plan Summary</h3>
        </div>
        <div class="panel-body">
            <div id="NewPlanForm" class="form-horizontal">
                @Html.AntiForgeryToken()
                @Html.HiddenFor(model => model.ID )
                <div class="form-group">
                    @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.KnockoutTextBoxFor(model => model.Name, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.Name)
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.Author, new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.KnockoutTextBoxFor(model => model.Author, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.Author)
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.ShortDescription, new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.KnockoutTextBoxFor(model => model.ShortDescription, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.ShortDescription)
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.LongDescription, new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.KnockoutTextAreaFor(model => model.LongDescription, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.LongDescription)
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.Discipline, new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.KnockoutTextBoxFor(model => model.Discipline, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.Discipline)
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.Level, new { @class = "control-label col-md-3" })
                    <div class="col-md-9">
                        @Html.KnockoutTextBoxFor(model => model.Level, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.Level)
                    </div>
                </div>
            </div>
            <div class="pull-right">
                <div id="btnSavePlan" class="btn btn-primary">Save Plan</div>
            </div>
        </div>
    </div>
</div>

<div id="SchedulePanel" class="panel panel-default">
    @Html.HiddenFor(model => model.ID)
    <div class="panel-heading">
        <h3>Plan Schedule</h3>
    </div>
    <div class="panel-body">
        <div class="pull-right">
            <input id="numWeeks" type="text" class="form-control input-sm" placeholder="number"/>
            <a id="btnAddWeek" class="btn btn-primary" data-bind="click: addWeek">Add Week(s)</a>
        </div>
        <div id="ScheduledInstructions">
            Click the Add Week button to get started adding workouts to your schedule
        </div>
        <hr />
        <div id="weeks" data-bind="template: { name: 'weekTemplate', foreach: Schedule}">
        </div>
    </div>
</div>

<script id="weekTemplate" type="text/html">
    <div style=" margin-left: auto; margin-right: auto; ">
        <h4 data-bind="text: Name"></h4>
        <div data-bind="id: weekName, template: { name: 'dayTemplate', foreach: Days }" >
        </div>
    </div>
</script>

<script id="dayTemplate" type="text/html">
    <div class="dayBuilder">
        <span data-bind="text: DayNumber"></span>
        <div data-bind="id: dayName, template: { name: 'workoutTemplate', foreach: Workouts }" >
        </div>
        <div class="addWorkout">
            <span class="glyphicon glyphicon-plus" data-bind="click: addWorkout" title="Add Workout"></span>
        </div>
    </div>   
</script>

<script id="workoutTemplate" type="text/html">
    <div class="workout">
        <span data-bind="text: Type"></span>
        <span class="glyphicon glyphicon-remove pull-right" data-bind="click: $parent.removeWorkout"></span>
    </div>
</script>

@ViewBag.HeaderText
计划摘要
@Html.AntiForgeryToken()
@Html.HiddenFor(model=>model.ID)
@LabelFor(model=>model.Name,新的{@class=“controllabel col-md-3”})
@Html.KnockoutTextBoxFor(model=>model.Name,新的{@class=“form control”})
@Html.ValidationMessageFor(model=>model.Name)
@LabelFor(model=>model.Author,新的{@class=“controllabel col-md-3”})
@Html.KnockoutTextBoxFor(model=>model.Author,new{@class=“form control”})
@Html.ValidationMessageFor(model=>model.Author)
@LabelFor(model=>model.ShortDescription,新的{@class=“controllabel col-md-3”})
@Html.KnockoutTextBoxFor(model=>model.ShortDescription,新的{@class=“form control”})
@Html.ValidationMessageFor(model=>model.ShortDescription)
@LabelFor(model=>model.LongDescription,新的{@class=“controllabel col-md-3”})
@Html.KnockoutTextAreaFor(model=>model.LongDescription,new{@class=“form control”})
@Html.ValidationMessageFor(model=>model.LongDescription)
@LabelFor(model=>model.规程,新的{@class=“controllabel col-md-3”})
@Html.KnockoutTextBoxFor(model=>model.production,新的{@class=“form control”})
@Html.ValidationMessageFor(model=>model.规程)
@LabelFor(model=>model.Level,新的{@class=“controllabel col-md-3”})
@Html.KnockoutTextBoxFor(model=>model.Level,新的{@class=“form control”})
@Html.ValidationMessageFor(model=>model.Level)
self.removeWorkout = function (workout) {
    // 'this' should represent the item that originated the call (a workout)  Not the case...
    self.Workouts.remove(workout);
};