2

地獄のすべて、

子モデルを持つ複雑なノックアウト ビューモデルが少しあります。ビューモデルの定義は次のとおりです。

var DailyItems = function (data) {
var p = this;
this.Date = ko.observable(data.Date);
this.Required = ko.observable(data.Required);
this.SetupTime = ko.observable(data.SetupTime);
this.CloseTime = ko.observable(data.CloseTime);
this.MinHrsPerDay = ko.observable(data.MinHrsPerDay);
this.MaxHrsPerDay = ko.observable(data.MaxHrsPerDay);
this.WorkSegments = ko.observableArray([]);
var records = $.map(data.WorkSegments, function (x) { return new WorkShift(p, x) });
this.WorkSegments(records);

this.EnableAdd =  ko.computed(function () {
    return this.WorkSegments().length < 8;
}, this);

this.Add = function () {
    var data = {
        Parent: p,
        ID: "",
        Date: this.Date,
        Location: UNIT_ID,
        Role: "",
        EmployeeRoles: this.WorkSegments()[0].EmployeeRoles(),//add the roles of the first work segment
        ShiftStart: "",
        ShiftEnd: ""
    };
    var child = new WorkShift(p, data);
    this.WorkSegments.push(child);      
}

this.Delete = function (item) {
    this.WorkSegments.remove(item);
}
};

var WorkShift = function (parent, data) {
var self = this;
this.Parent = ko.observable(parent);
this.ID = ko.observable(data.ID);
this.Day = ko.observable(data.Day);
this.Location = ko.observable(data.Location);
this.ShiftStart = ko.observable(data.ShiftStart);
this.ShiftEnd = ko.observable(data.ShiftEnd);
this.EmployeeRoles = ko.observableArray(data.EmployeeRoles);

this.Location.subscribe(function (branchId) {
    $.ajax({
        type: "POST",
        url: SERVER_PATH + '/WebServices/AttributeService.asmx/GetDataOnLocationChange',
        data: "{" + "clientId: '" + CLIENT_ID
                    + "', unitId: '" + branchId
                    + "', effectiveDate:'" + EFFECTIVE_DATE
                    + "'}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (res) {
            var d = JSON.parse(res.d);
            self.EmployeeRoles(d.Roles);

            var tasks = self.Parent().WorkSegments();
            //Requirement: for any day of the week, if there is more than one work segment
            //at different branches the required type should be set to 'On' and made disable
            if (tasks.length > 1) {
                for (var i = 0; i < tasks.length; i++) {
                    if ((d.IsSection == false && tasks[i].Location() != self.Location()) || (d.IsSection == true && self.ParentBranch() != tasks[i].ParentBranch())) {
                        self.Parent().Required('O');
                    }
                    else {
                        self.Parent().Required('E');
                    }
                }
            }
        },
        error: HandleLocationChangeError
    });
}.bind(this));

this.Role = ko.observable(data.Role);
}

ここで何が起こるかというと、DailyItems() で観測可能な Location() はドロップダウン リストからの値であり、メイン ビューモデルを通じて入力されます。場所が変更されると、選択された場所に応じて EmployeeRoles() observablearray が変更される必要があるため、Location.Subscribe メソッドが使用されます。

私の問題は、このサブスクリプション メソッドが最初のデータの読み込み中でも呼び出されることです。そのため、最初にサーバーへの不要な呼び出しがあります。ユーザーが実際にドロップダウンの選択を変更したときにのみ呼び出されるようにしたい。

これを達成するにはどのようなオプションが必要ですか?

よろしく、チャトゥ

4

3 に答える 3

1

データを WorkShift コンストラクターに渡すと、観測可能な場所で変更イベントがトリガーされます。1 つの方法は、子オブジェクトが構築され、オブザーバブルに初期値が設定されたで、.subscribe 呼び出しを親オブジェクトに移動することです。

Add 関数は次のようになります。

this.Add = function () {
    var data = {
        // SNIP
    };
    var child = new WorkShift(p, data);

    child.subscribe(function (branchId) {
        $.ajax({ 
            // SNIP       
            });
    }.bind(child)); // <--- important to use child and not 'this'!!!

    this.WorkSegments.push(child);
};

this コンテキストを子にバインドしたため、ajax 呼び出し内で「self」の代わりに「this」を使用する必要もあります。

于 2013-03-18T21:04:20.193 に答える
0

以下は私のUIバインディングです。

<tbody data-bind="foreach: WorkSegments">
                                            <tr>
                                                <td class="formFields">

                                                   ct class="combobox" data-bind="options:$root.WorkLocations, value:Location, optionsText: 'Name', optionsValue: 'ID', enable: LocationActive"

                                                        style="font-size: x-small; font-style: normal; font-family: Tahoma; width: 80px">
                                                    </select>
                                                </td>
                                            </tr>
                                        </tbody>

ここで、ドロップダウンオプションはメインビューモデルから設定されます。その後、選択した要素がバインドされます。その後、初期ロード時にコードをデバッグすると、Locationsubscribeメソッドが呼び出されます。

于 2013-03-18T16:58:42.727 に答える