2014-02-01 4 views
1

У меня есть модель с несколькими вложенными наблюдаемыми массивами, и мне нужно вызвать функцию для удаления элементов из одного из массивов. Вместо диаграммы я попытаюсь описать модель на английском языке (она также включена ниже в код). Модель представления - это план обучения, который имеет наблюдаемый массив недельных объектов. Каждый объект недели, среди других свойств, имеет объект observableArray of Days. Каждый день объект, среди других свойств, имеет наблюдаемый массив объектов тренировки. Каждый объект тренировки, среди других свойств, имеет наблюдаемый массив объектов Interval. Я новичок в нокауте и не все, что у меня на ногах с javascript (и, возможно, некоторые вещи здесь не так, пожалуйста, не стесняйтесь критиковать). Проблема заключается в функции removeWorkout на объекте Day. Я следую примеру 2 на сайте нокаута здесь: example. Я думаю, что я делаю то, что говорит страница, но когда я проверяю «это» в функции, это объект «День», а не «объект тренировки», который вызывает эту функцию. Где я иду не так?Вызывающие функции в вложенных наблюдаемых массивах (knockout.js)

Мой 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(); 
    }; 
}); 

Мое мнение:

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

ответ

1

removeWorkout() "принадлежит" $parent, что в день, а не тренировки; поэтому this - день объект. Нокаут поставляет модель, инициировавший вызов в качестве первого параметра, так что это должно работать ...

self.removeWorkout = function (workout) { 
    // 'this' should represent the item that originated the call (a workout) Not the case... 
    self.Workouts.remove(workout); 
}; 

Edit: Вот Документах (примечание 1) ... Knockout: The "click" binding

+0

Brilliant! Не поймал, что нокаут уже пропустил элемент с кликом. Спасибо Энтони! –

Смежные вопросы