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() 可观察数组,因此 Location.Subscribe 方法。

我的问题是即使在初始数据加载期间也会调用此订阅方法。所以一开始就对服务器进行了不必要的调用。我只希望在用户实际更改下拉选择时调用它。

我有什么选择来实现这一目标?

问候, 查图

4

3 回答 3

1

将数据传递到 WorkShift 构造函数中会触发可观察位置上的更改事件。一种方法是在构造子对象并且可观察对象具有其初始值之后将 .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);
};

然后,您还必须在 ajax 调用中使用“this”而不是“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>

这里的下拉选项是从主视图模型中设置的。之后,选定的元素被绑定。之后,当我在初始加载时调试代码时,会调用 Location subscribe 方法。

于 2013-03-18T16:58:42.727 回答
0

如果是第一次更改,它会不会像不运行 AJAX 调用一样简单?它不漂亮,但很简单:

var locationInitialized = false;
this.Location.subscribe(function (branchId) {
    if (!locationInitialized) {
         locationInitialized = true;
         return;
    }
    $.ajax({
    ...

当然,您可以改为在初始填充成功函数中设置 locationInitialized。

或者,设置函数,但在初始填充完成之前不要订阅它。@explunit 展示了一种方法来做到这一点。

于 2014-11-15T03:46:02.670 回答