2013-03-18 103 views
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(觀察到的)是從下拉列表,它是通過主視圖模型填充的值。當位置改變時,它應該根據所選位置更改EmployeeRoles()observablearray,因此是Location.Subscribe方法。

我的問題是,即使在初始數據加載期間,該訂閱方法也會被調用。所以在開始時就有一個對服務器不必要的調用。我只希望在用戶實際更改下拉選擇時調用它。

我有什麼方法可以實現這個目標?

問候, Chathu

+0

我沒有看到它在初始加載時被調用。我是否缺少一些代碼?這裏是我從你提供的東西創建的小提琴。 http://jsfiddle.net/sujesharukil/ywEP2/ – 2013-03-18 15:14:57

回答

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訂閱方法被調用。

1

將數據傳遞到WorkShift構造函數是觸發位置observable上的change事件的原因。一種方法是在構建子代後將.subscribe調用移動到父對象,並且可觀察值具有其初始值。

你的附加功能會再看看這樣的事情:

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調用裏面,因爲你已經綁定的這方面孩子。

+0

感謝您的答案,像這樣處理訂閱調用不會將其註冊到現有的WorkShift()對象不是嗎?另外,如果我在WorkShift對象上進行訂閱調用,那麼當位置發生更改時它將如何觸發? – devC 2013-03-19 05:01:19

+0

@chathuranganiePathirage這個解決方案在另一個項目上爲我工作。試試看,讓我知道它是否適合你。 – explunit 2013-03-19 11:53:00

0

如果它是第一次更改,它可以像運行AJAX調用一樣簡單嗎?它並不漂亮,但很簡單:

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

當然,您可以在初始人口成功函數中設置locationInitialized。

另外,設置功能,但不訂閱它,直到完成初始人口。 @explunit顯示了一種方法來做到這一點。