0

私はこのようなビューモデルを持っています:

var Jobs = [
    { "Id": "J01", "Value": "description1" }, 
    { "Id": "J02", "Value": "description2" }, 
    { "Id": "J03", "Value": "description3" }
]

var Tasks = []

var Line = function (obj) {
    var self = this;
    self.Job    =   ko.observable(obj.JobId)
    self.Task   =   ko.observable(obj.TaskId)

    self.Job.subscribe(function () {
        /*
        Here i want to run ajax and fetch tasks for that 
        job and i assume this should work for related tasks dropdown only
        */
    });
}

function ViewModel() {
    var self = this
    self.Timesheet = ko.observable()
    self.LoadData = function () {

        var data = {
            "timesheet": {
                "ApprovalStatus": 1,
                "Description": "Timesheet",
                "PeriodFrom": "2013-09-01",
                "PeriodTo": "2013-09-15",
                "RecId": "1",
                "Lines": [{
                    "DestinationRecId": "D01",
                    "LaborCategoryRecId": "C01",
                    "PayTypeRecId": "PAY-01",
                    "ProjectRecId": "J01",
                    "ProjectWBSRecId": "J01-T01",
                    "RecId": "1"

                }, {
                    "DestinationRecId": "D02",
                    "LaborCategoryRecId": "C01",
                    "PayTypeRecId": "PAY-02",
                    "ProjectRecId": "J02",
                    "ProjectWBSRecId": "J02-T01",
                    "RecId": "2"
                }
            }
        }   

        self.Timesheet(data.timesheet)

        for (var i = 0; i < data.timesheet.Lines.length; i++) {
            var line = self.Timesheet().Lines[i]
            var obj =   {
                JobId           :   line.ProjectRecId,
                TaskId          :   line.ProjectWBSRecId
            }
            /*  Here i am adding property SelectedItem and 
            * in it assigning a child object
            */
            self.Timesheet().Lines[i].SelectedItem      =   new Line(obj)
            console.log(self.Timesheet().Lines[i])
        }   
    }

    self.LoadData()
}

対応するビューは次のとおりです。

<table>
    <thead>
        <tr>
            <th>Job </th>
            <th>Job WBS</th>
        </tr>
    </thead>    
    <tbody id="lines" data-bind="foreach:Timesheet().Lines">
    <tr>
        <td>
            <select 
                data-bind="
                options: Jobs,  
                optionsText: 'Value', 
                optionsValue: 'Id',
                optionsCaption: 'Select Job',
                value : $data.ProjectRecId
                "
                class="m-wrap">
                <!-- $data.ProjectRecId $data.SelectedItem.Job-->
            </select>
        </td>
        <td data-bind="with: Jobs">
            <select
                data-bind="
                options: Tasks, 
                optionsText: 'Value', 
                optionsValue: 'Id', 
                value : $data.ProjectWBSRecId,
                optionsCaption: 'Select Task'
                "
                class="m-wrap">
            </select>
        </td>
    </tr>
    </tbody>
</table>

問題は、私が使用すると定義されていない$data.SelectedItem.Jobと言うことです。 使用しても問題なく動作します。目標は、「ノックアウト依存ドロップダウン処理」のようなものを達成することです。SelectedItem
$data.ProjectRecId

ドロップダウンを個別に処理したいのですが、失敗しています。

出力:

ここに画像の説明を入力

4

1 に答える 1

1

私の実装を見てください。

基本的に、私は 注 3 を使用しました: 「as」を使用して「foreach」アイテムにエイリアスを与え、に直接接続できるようself.Timesheet().Lines[i].SelectedItemJobTaskますvalue binding

「タスク」コンボ ボックスのバインディングを関数呼び出しに置き換えるoptionsことで、その行で選択された「ジョブ」に基づいてカスタム値をロードできます。によって設定された元の値self.Task = ko.observable(obj.TaskId)が関数によって返されるオプションに存在する場合、それが選択/表示されます。

その例で使用されているビューモデルdataは、提供したオブジェクトとはまったく異なる構造になっているため、実装は提供したチュートリアルとまったく同じではありません。私は独自のプロパティに移動Jobsし、行を反復するときにそのデータを個別にクエリ/構築できると想定しました。それ以外の場合は、ジョブ/タスクのペアを並べて配置するのではなく、1 つのジョブを複数のタスクに関連付けるようにデータを構造化する必要があります。データ構造が変更された場合、提供された例により密接に結び付いた実装が実現可能になります。

HTML :

<button data-bind="click:printLines">Print Lines</button>
  <table>
     <thead>
      <tr>
        <th>Job </th>
        <th>Job WBS</th>
      </tr>
     </thead>    
     <tbody id="lines" data-bind="foreach: {data: Timesheet().Lines, as: 'line'}">
      <tr>
       <td>
        <select 
            data-bind="
            options: $root.Jobs,  
            optionsText: 'Value', 
            optionsValue: 'Id',
            optionsCaption: 'Select Job',
            value : line.SelectedItem.Job
            "
            class="m-wrap">
            <!-- $data.ProjectRecId $data.SelectedItem.Job-->
        </select>
       </td>
       <td data-bind="with: line.SelectedItem.Job">
        <select
            data-bind="
            options: $root.getAvailableTasks(line.SelectedItem.Job), 
            optionsText: 'Value', 
            optionsValue: 'Id', 
            value : line.SelectedItem.Task,
            optionsCaption: 'Select Task'
            "
            class="m-wrap">
        </select>
       </td>
      </tr>
     </tbody>
 </table>

Javascript :

var Line = function (obj) {
  var self = this;
  self.Job    =   ko.observable(obj.JobId)
  self.Task   =   ko.observable(obj.TaskId)

  self.Job.subscribe(function () {
    /*
    Here i want to run ajax and fetch tasks for that 
    job and i assume this should work for related tasks dropdown only
    */
  });
}

function ViewModel() {
  var self = this;
  self.Jobs = ko.observableArray([
                                 { "Id": "J01", "Value": "description1" }, 
                                 { "Id": "J02", "Value": "description2" }, 
                                 { "Id": "J03", "Value": "description3" }
                                 ]);

  self.formattedData = ko.observableArray([]);

  self.Timesheet = ko.observable()
  self.LoadData = function () {

    var data = {
        "timesheet": {
            "ApprovalStatus": 1,
            "Description": "Timesheet",
            "PeriodFrom": "2013-09-01",
            "PeriodTo": "2013-09-15",
            "RecId": "1",
            "Lines": [{
                "DestinationRecId": "D01",
                "LaborCategoryRecId": "C01",
                "PayTypeRecId": "PAY-01",
                "ProjectRecId": "J01",
                "ProjectWBSRecId": "J01-T01",
                "RecId": "1"

            }, {
                "DestinationRecId": "D02",
                "LaborCategoryRecId": "C01",
                "PayTypeRecId": "PAY-02",
                "ProjectRecId": "J02",
                "ProjectWBSRecId": "J02-T01",
                "RecId": "2"
            }]
        }
    }   


    self.Timesheet(data.timesheet)

    for (var i = 0; i < data.timesheet.Lines.length; i++) {
        var line = self.Timesheet().Lines[i]
        var obj =   {
            JobId           :   line.ProjectRecId,
            TaskId          :   line.ProjectWBSRecId
        }
        /*  Here i am adding property SelectedItem and 
        * in it assigning a child object
        */

        line.SelectedItem      =   new Line(obj);   
    }   
}
self.printLines = function() {
  for (var i = 0; i < self.Timesheet().Lines.length; i++) {
      var selectedItem = self.Timesheet().Lines[i].SelectedItem;
      console.log('Job: ' + selectedItem.Job() + " Task: " + selectedItem.Task());
  }
}

self.getAvailableTasks=function(selectedJob) {

    //your ajax would move here
    if("J01" == selectedJob()){
        return  ko.observableArray([{"Id": "J01-T01", "Value": "TaskJ01-T01Value"},
                                {"Id": "J01Task02", "Value": "Task02Value"}]);
    }
    else {
      return  ko.observableArray([{"Id": "DefaultTask01", "Value": "Task01Value"},
                                {"Id": "DefaultTask02", "Value": "Task02Value"}]);
    }
 }

 self.LoadData()
}

ko.applyBindings(new ViewModel())
于 2013-10-25T05:15:33.600 に答える