2013-03-18 4 views
2

지옥 전체,녹아웃 구독 문제

나는 하위 모델이있는 복잡한 녹아웃 뷰 모델을 가지고 있습니다. 여기에 일어나는 DailyItems (의 관측 위치는()) 메인 뷰 모델을 통해 채워지는 드롭 다운리스트에서 값입니다 무엇

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); 
} 

: 다음은 뷰 모델 정의입니다. 위치가 변경되면 선택한 위치, 즉 Location.Subscribe 메소드에 따라 EmployeeRoles() observablearray가 변경되어야합니다.

제 문제는이 구독 메서드는 초기 데이터로드 중에도 호출된다는 것입니다. 그래서 처음에는 불필요한 서버 호출이 있습니다. 사용자가 실제로 드롭 다운 선택을 변경할 때만 호출되기를 원합니다.

이 옵션을 얻으려면 어떤 옵션이 필요합니까?

감사합니다, Chathu 내 UI가 결합되어 다음

+0

초기로드에서 호출되는 것을 보지 못했습니다. 코드가 누락 되었습니까? 여기 당신이 제공 한 것으로부터 창조 한 바이올린이 있습니다. http://jsfiddle.net/sujesharukil/ywEP2/ –

답변

0

: 드롭 다운 옵션이 메인 뷰 모델에서 설정

다음
<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 메서드가 호출됩니다.

1

데이터를 WorkShift 생성자로 전달하면 관찰 할 수있는 위치에서 변경 이벤트가 트리거됩니다. 한 가지 방법은 이후 자식 개체가 생성되고 관찰 가능 개체가 초기 값을 가지므로 자식 개체를 부모 개체 으로 이동하는 것입니다.

귀하의 추가 기능은 다음과 같이 보일 것입니다 : 당신이 아이에게이 상황을 구속 한 이후

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); 
}; 

당신은 다음 또한 "이"대신 아약스 호출 내 "자기"의 사용하는 것 .

+0

답변을 주셔서 감사합니다. 구독 통화를 처리하면 기존 WorkShift() 객체에 등록되지 않습니다. 또한 WorkShift 객체에 subscribe 호출을하면 위치가 변경 될 때 어떻게 트리거됩니까? – devC

+0

@chathuranganiePathirage이 솔루션은 다른 프로젝트에서 저에게 효과적이었습니다. 시도해보고 그것이 효과가 있는지 알려주세요. – explunit

0

처음 변경된 경우 AJAX 호출을 실행하지 않는 것처럼 간단 할 수 있습니까? 예쁘지는 않지만 간단합니다.

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

물론 초기 채우기 성공 함수에서 locationInitialized를 설정할 수 있습니다.

또는 기능을 설정하고 초기 채우기가 완료 될 때까지 구독하지 마십시오. @explunit은이를 수행하는 한 가지 방법을 보여주었습니다.