2013-08-27 48 views
4

我已經創建了一個自定義綁定處理程序來呈現html選擇組件。模板中的Knockout自定義綁定處理程序

EG:

<select data-bind="dynamicSelect: { src: 'Category', label: 'Category'} "></select> 

在用戶選擇的類別,該類別字段數組被填充,我已經綁定到的div會呈現一定的樣板

<div data-bind="template: { name: displayMode, foreach: categoryFields }"></div> 

我模板

<script type="text/html" id="inputTemplate"> 
    <label data-bind="text: FieldName, attr: { for: FieldName }"></label> 
    <input data-bind="attr: { name: FieldName, type: $parent.fieldType($data) }" /> 
</script> 
<script type="text/html" id="lookupTemplate"> 
    <label data-bind="text: FieldName, attr: { for: FieldName }"></label> 
    <select data-bind="dynamicSelect: { src: FieldName, label: FieldName}"></select> 
</script> 

問題是,dyn模板裏面的amicSelect好像不具有約束力?我將如何去重用模板內的綁定處理程序?

裝訂處理器

define(['durandal/composition', 'plugins/http'], function (composition, http) { 
    composition.addBindingHandler('dynamicSelect', { 
     init: function (element, valueAccessor) { 
      console.log(element); 
      console.log(valueAccessor()); 
      var elem = $(element); 
      elem.addClass('hidden'); 
      elem.before('<label>' + valueAccessor().label + '</label>'); 
      elem.after('<div><br/><label><i class="icon-spinner icon-spin active"></i> Loading...</label></div>'); 

      console.log('/api/lookup?type=' + valueAccessor().src); 
      return http.get('/api/lookup?type=' + valueAccessor().src).then(function (res) { 
       var items = res.LookupItems; 
       $.each(items, function (idx) { 
        elem.append('<option value=' + items[idx].Id + '>' + items[idx].Name + '</option>'); 
       }); 
       elem.removeClass('hidden'); 
       elem.next().addClass('hidden'); 
      }); 

     }, 
     update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 

     } 
    }); 
}); 
+0

好奇的問題,當我們有能力使用KO爲什麼你使用jQuery來渲染視圖? – Anders

+0

我還是一個全新的淘汰賽,所以這是我最好的嘗試......你能否提供代碼/鏈接來處理我的觀點,或提供代碼以及你的建議?所有我知道的是目前的調用似乎並沒有執行期間模板綁定.. –

回答

1

找到了我的問題。

我註冊了綁定處理程序使用Durandals,組成助手。因此(和我最好的猜測),它只在頁面創建時被調用。解釋爲什麼我的第一個選擇填充。

我改變了我的綁定處理程序

define(['plugins/http'], function (http) { 
    ko.bindingHandlers.dynamicSelect = { 
     init: function (element, valueAccessor) { 
      var elem = $(element); 
      elem.addClass('hidden'); 
      elem.before('<label>' + valueAccessor().label + '</label>'); 
      elem.after('<div><br/><label><i class="icon-spinner icon-spin active"></i> Loading...</label></div>'); 

      console.log('/api/lookup?type=' + valueAccessor().src); 
      return http.get('/api/lookup?type=' + valueAccessor().src).then(function (res) { 
       var items = res.LookupItems; 
       $.each(items, function (idx) { 
        elem.append('<option value=' + items[idx].Id + '>' + items[idx].Name + '</option>'); 
       }); 
       elem.removeClass('hidden'); 
       elem.next().addClass('hidden'); 
      });  
     } 
    }; 
}); 
+0

給我幾個哨兵,在小提琴工作 – Anders

+0

真棒! :D我仍然渴望學習。謝謝! –

1

這不回答你的迪朗達爾相關型號的問題,但它解決了你缺乏在你的代碼MVVM心態。 :d

我會做它有一個ViewModel

MyApp.LookupViewModel = function(label, src) { 
    this.label = label; 
    this.src = src; 
    this.items = ko.observableArray(); 
    this.selectedItem = ko.observable();  
    this.loading = ko.observable(true); 
    this.loaded = ko.computed(function() { 
     return !this.loading(); 
    }, this); 


    //simulate ajax 
    setTimeout(function() { 
     this.items([{ 
       name: "Foo1", 
       id: 1 
      },{ 
       name: "Foo2", 
       id: 2 
      } 

     ]); 
     this.loading(false); 
    }.bind(this), 1000); 
}; 

當你想使用它,你只需要聲明的VM

MyApp.ViewModel = function() { 
    this.lookup = new MyApp.LookupViewModel("Foo", "http://foo"); 
} 

http://jsfiddle.net/Vjzn6/1/

我上面搗鼓應用實例我的一個小庫,負責查找視圖名稱,以便您不需要在視圖中顯式聲明模板綁定。

+0

將用戶界面中的選項>項目重新命名爲不同 – Anders

相關問題