2014-07-24 2 views
2

며칠 전에 this 질문을하고 정말 멋진 답변을 얻었습니다. 이후로 나는 모든 standart 검도 구성 요소를 mvvm 규칙에 따라 사용하므로 my custom widget을 사용할 수 있는지 궁금합니다. 그리고 커스텀 위젯의 어떤 부분을 편집해야합니까? 예를 들어 :사용자 정의 검도 위젯에 대한 Mvvm 지원

<div id="dropdowns" data-role="linkeddropdowns" data-period="YEAR" 
    data-bind="year: selectedYear"></div> 

감사합니다,

+0

위젯 생성을위한 kendo 튜토리얼을 참조하십시오 : -http : //blogs.telerik.com/kendoui/posts/12-04-03/creating_custom_kendo_ui_plugins –

답변

3

나는 검도 UI가 중첩 뷰 모델 바인딩에 대한 좋은하지 않는 경향이 있기 때문에 당신이 내부 뷰 모델 접근 방식 문제로 실행할 수 있습니다 생각합니다. 내가 아는 한, 모든 검도 UI 위젯은 그 때문에 내부 위젯을 코드로 작성합니다.

사이드 노트 : 위젯에서 DOM 요소를 드롭 다운 요소로 사용했습니다. 동일한 페이지에 위젯을 여러 개 만들면 중복이 생성됩니다. 이 경우 클래스를 사용하는 것이 좋습니다.

getYear: function() { 
    return this._getWidget("year").value(); 
}, 

setYear: function (value) { 
    this._getWidget("year").value(value); 
    console.log(this._getWidget("year")); 
} 

전체 :

kendo.data.binders.widget.year = kendo.data.Binder.extend({ 
    init: function (element, bindings, options) { 
     kendo.data.Binder.fn.init.call(this, element, bindings, options); 

     var that = this; 
     that.element.bind("change", function() { 
      that.change(); //call the change function 
     }); 
    }, 
    refresh: function() { 
     var that = this, 
      value = that.bindings.year.get(); 

     this.element.setYear(value); 
    }, 
    change: function() { 
     var value = this.element.getYear(); 
     this.bindings.year.set(value); 
    } 
}); 

이 이러한 접근을 제공하는 위젯 작동합니다 :

는 다음과 같이 보일 수있는하는 custom binder을해야하는 year 바인딩을 사용하려면 위젯 예제 (완전히 구현되지 않았 음을 유의하십시오 - 연도 바인딩과 기간 설정 만 고려함) :

(function ($) { 
    var kendo = window.kendo, 
     ui = kendo.ui, 
     Widget = ui.Widget, 
     periods = [ 
      { text: "PERIOD: YEAR", value: "YEAR" }, 
      { text: "PERIOD: QUARTER", value: "QUARTER" } 
     ], 
     quarters = [ 
      { text: "1. Quarter", value: 1 }, 
      { text: "2. Quarter", value: 2 }, 
      { text: "3. Quarter", value: 3 }, 
      { text: "4. Quarter", value: 4 } 
     ], 
     years = [2011, 2012, 2013, 2014]; 

    var LinkedDropDowns = Widget.extend({ 
     init: function (element, options) { 
      var that = this, 
       periodOption = $(element).data("period"); 
      if (periodOption) { 
       this.options.period = periodOption; 
      } 

      Widget.fn.init.call(that, element, options); 
      that._create(); 

      // make sure view state is correct depending on selected period 
      this._getWidget("period").trigger("change"); 
     }, 

     options: { 
      name: "LinkedDropDowns", 
      period: "YEAR", 
      periods: periods, 
      year: 2011, 
      years: years, 
      quarter: 1, 
      quarters: quarters, 
      selectedYear: 2011 
     }, 

     onPeriodChange: function (e) { 
      switch (e.sender.value()) { 
       case "YEAR": 
        $(this._getWidget("year").wrapper).show(); 
        $(this._getWidget("quarter").wrapper).hide(); 
        break; 
       case "QUARTER": 
        $(this._getWidget("year").wrapper).show(); 
        $(this._getWidget("quarter").wrapper).show(); 
        break; 
       default: 
        break; 
      } 
     }, 

     onChange: function() { 
      // trigger change so the binder knows about it 
      this.trigger("change", { sender: this }); 
     }, 

     _getWidget: function (name) { 
      var el = $(this.element).find("input." + name).first(); 
      return el.data("kendoDropDownList"); 
     }, 

     _create: function() { 
      var that = this; 

      // create dropdowns from templates and append them to DOM 
      that.periodDropDown = $(that._templates.periodDropDown); 
      that.yearDropDown = $(that._templates.yearDropDown); 
      that.quarterDropDown = $(that._templates.quarterDropDown); 

      // append all elements to the DOM 
      that.element.append(that.periodDropDown) 
       .append(that.yearDropDown) 
       .append(that.quarterDropDown); 

      $(this.element).find(".period").kendoDropDownList({ 
       dataTextField: "text", 
       dataValueField: "value", 
       value: this.options.period, 
       change: this.onPeriodChange.bind(that), 
       dataSource: this.options.periods 
      }); 

      $(this.element).find(".year").kendoDropDownList({ 
       dataSource: this.options.years, 
       change: this.onChange.bind(this) 
      }); 

      $(this.element).find(".quarter").kendoDropDownList({ 
       dataTextField: "text", 
       dataValueField: "value", 
       dataSource: this.options.quarters 

      }); 
     }, 

     _templates: { 
      periodDropDown: "<input class='period' />", 
      yearDropDown: "<input class='year' style='width: 90px' />", 
      quarterDropDown: "<input class='quarter' style='width: 110px' />" 
     }, 

     getYear: function() { 
      return this._getWidget("year").value(); 
     }, 

     setYear: function (value) { 
      this._getWidget("year").value(value); 
      console.log(this._getWidget("year")); 
     } 
    }); 

    ui.plugin(LinkedDropDowns); 
})(jQuery); 

(demo)

3

위젯에 추가 코딩이 필요하지 않습니다. 선언적 초기화를위한 위젯을 사용하려면 다음을 수행 할 수 있습니다

HTML

<div id="dropdowns" data-role="linkeddropdowns" data-period="QUARTER" data-year="2014"></div> 

이러한 데이터 속성은 위젯에서 "년"과 "2011"의 기본 옵션보다 우선합니다.

자바 스크립트 대신 $('#dropdowns').kendoLinkedDropDowns()를 호출

(function() { 
    kendo.init($('body')); 
})(); 

, 단지 kendo.init()를 호출하고 위젯은 자체 결합을 담당한다.

Here은 업데이트 된 작동 JSBin 예제입니다.

+0

Lars가 제안한 템플릿에서'id' 속성을 삭제했습니다. 그의 대답. 그는 맞습니다 - 한 페이지에서 두 번 이상 사용될 수있는 위젯 구성 요소에'id' 속성을 사용하지 않으려합니다. – Brett

관련 문제