2014-04-22 2 views
0

사용자 정의 드롭 다운을 만들려고합니다. 모든 요소를 ​​가져올 메서드 이름을 가지며 녹아웃 모델 바인딩 전에 목록이 채워질 때까지 기다려야합니다. 주어진 메소드에서 가져온 후 기본 동작을 시작합니다.녹아웃의 사용자 지정 드롭 다운 목록

지금까지 주어진 방법으로 데이터를 채우는 데 성공했습니다. 하지만 문제는 내 init 메소드가 비동기 작업을 완료 할 때까지 녹아웃 바인딩을 기다리는 방법을 알려주는 것입니다. Extender이 작업을 수행 할 수

ko.bindingHandlers.serviceMethod = { 
     init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
     var serviceName, optionsValue, optionsText, value, optionsCaption, isCompleted; 

     if (element.nodeName == 'SELECT') {     
      optionsValue = allBindings().optionsValue || 'value'; 
      optionsText = allBindings().optionsText || 'text';     
      serviceName = valueAccessor();    

      var l = $(element); 
      serviceName.apply().done(function (results) { 
       l.empty(); 
       $.each(results.List, function (j, result) { 
        l.append($("<option />").val(result[optionsValue] || '').text(result[optionsText] || '')); 
       })      
      }); 
     } 
    }, 
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 

     //what to do now in order to let knockout wait for list to be populated 
    } 
} 

내 바인딩

는, 데이터를 사용할 수있을 때까지

<select name="state" data-bind="serviceMethod:registrationService.getAllStates,value: model.state" id="ddlState"></select> 

답변

1

당신은 입력 요소를 비활성화 할 수 있습니다.

마크 업 :

<select data-bind="serviceMethod:getOptions, options: options, enable:options.enable></select> 

뷰 모델 :

function viewModel(){ 
    this.options=ko.observableArray().extend({ enabled:false});  
} 

바인딩 핸들러 :

ko.bindingHandlers.serviceMethod = { 
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
     var getOptionsFunction=valueAccessor(); 
     // deferred implemented as a callback 
     getOptionsFunction(function(r){ 
      allBindings().options(r);    
      // call extender observable to enable the input 
      allBindings().options.enabled(true); 
     }); 
    }, 
    update:function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
    }  

증량제 :

ko.extenders.enabled = function(target, option) { 
    target.enabled=ko.observable(option); 
    return target; 
}; 
,

fiddle

참고 : 내가보기 모델에 논리를 움직일 것입니다, 우리의 프로젝트에 우리가 viewModels에 가야 바인딩 처리기에 너무 많은 코드를 넣어 실수를했다.

+0

처럼 사용 나는 그것을 달성하는 방법, 처음에는 확장되어 그 답장을 보내 주셔서 감사합니다, 솔루션은 좋지만 그 같은 드롭 다운 목록을 사용하지만 내가 원하는 것은 g 옵션을 선택하는 것입니다. 서버에서 iven. 매핑 플러그인을 사용하고 있습니다. 두 피들 렛을 살펴 보아라. 첫 번째 것은 내가해야 할 일이다. 대신 연기 된 응답의 값을 선택하는 것은 JSON 형식의 서버에서이 값을 사용하여 매핑 플러그인에서 뷰 모델을 가져 오는 데 사용된다. http://jsfiddle.net/u578D/1/ http://jsfiddle.net/R26pr/1/ –

+0

두 번째 익스텐더를 사용하여 관측 대상을 게으른 초기화하도록 약간 변경했습니다. http://jsfiddle.net/R26pr/2/ – Martijn

+0

이 상황을 처리하는 좋은 방법입니다, 나는 'populated'라는 관측 가능 변수를 기반으로 아약스 기반 변수를 확장하고 아약스 응답을받을 때마다 onDemandObservable에서 true로 만듭니다. 서버에서 내 viewModel에서 모든 아약스 기반 observables에 대한 계산 된 observable을 채우고 지연된 객체를 반환했으며 모듈 부트 스트랩 파일에 바인딩을 적용했습니다. –

1

ko.extenders.asyncList = function (target, option) { 

    var _callbackF = []; 
    var result = ko.computed({ 
     read: function() { 

      if (!target.populated()) { 
       option.apply().done(_addintoList); 
      } 
      return target; 
     }, 
     deferEvaluation: true 
    }); 

    target.populated = ko.observable(false); 
    target.refresh = function() { 
     target.populated(false); 
    }  
    var _addintoList = function (aData) { 

     ko.utils.arrayForEach(aData.List, function (item) { 
      target.push(item); 
     }); 

     if (_callbackF != undefined) { 
      $.each(_callbackF, function (_f) { 
       _f.apply(); 
      }); 
      _callback = undefined; 
     } 
     target.populated(true); 
    } 
    return result(); 
} 

다음

staticData: function() { 
    var self = this; 
    var def = $.Deferred(); 
    self.allStates = ko.observableArray().extend({ asyncList: registrationService.getAllStates }); 
    self.hearUsAll = ko.observableArray().extend({ asyncList: registrationService.getAllSources });; 
    self.populated = ko.computed({ 
     read: function() { 
      if (this.allStates.populated() && this.hearUsAll.populated()) { 
       return def.resolve(true); 
      } 
      return def; 
     }, 
     deferEvaluation: true 
    }, this); 

처럼이 확장을 사용하여 모델을 볼

같은 녹아웃은 내 주요 기능은

this.staticData.populated().done(
     function (d) { 
      ko.applyBindings({ model: self.dataModel, staticData: self.staticData, view: self.viewModel }) 
     }); 
+0

이보다 더 나은 해결책을 찾도록 전문가가 도와 줄 수 있다면이 내용을 공유합니다. –

관련 문제