2013-11-15 34 views
3

我們環境中的典型場景是允許用戶選擇由服務器(終端,產品,..)提供的選項列表,以及然後呈現所請求的數據。如何使用預定義的文本和值選項定義自定義挖空「選項綁定」

由服務器提供的選項是在名稱,ID的格式,並因此以下敲除構建體中使用的所有經常:

<select data-bind="options: serverOptions, optionsText: 'Name', optionsValue: 'ID', value: selectedOption> 

這將是理想的是使自定義bindingHandler,叫做「NamedIdOptions」在allBindingsAccessor()上指定optionsText和optionsValue,然後重定向到標準選項綁定處理程序。

<select data-bind="NamedIdOptions: serverOptions, value: selectedOption"></select> 

此之前,我已經做自己的綁定填補了選項我自己的處理程序 - 但是,我更願意使用由選項結合處理器提供了框架。

我試過不同的方法沒有太多的成功 - 選項綁定使用allBindings ['optionsValue']和allBindings ['optionsText']來訪問該值,似乎我沒有辦法設置這些。 (我想,以避免在使用applyBindingsToNode方法寫的線沿線的東西:

ko.bindingHandlers.NamedIdOptions = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) 
    { 
     var allBindings = allBindingsAccessor(); 
     allBindings.*FORCESET*("optionsText", "Name"); 
     allBindings.*FORCESET*("optionsValue", "ID"); 

     retun ko.bindingHandlers.options.init.apply(this, arguments); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) 
    { 
     retun ko.bindingHandlers.options.update.apply(this, arguments); 
    } 
} 

然而,好像我沒有方法可行設置在allBindings任何

我不允許。使用

allBindings['_ko_property_writers']['optionsText']("Name"); 
allBindings['_ko_property_writers']['optionsValue']("ID"); 

我真的希望避免applyBindingsToNode在init構造爲

Knockout - is it possible to combine standard select bindings with a custom binding?

有沒有人現在就解決問題的簡單方法?

+0

我不知道這是否準確回答你的問題,但是如果你正在創建一個可重用的控件,你總是可以使用computedOptions和computedName,並且它們是被設置爲任何傳入值的可觀察值。 –

+0

在以前的Knockout版本中,您曾經能夠獲得與添加optionsText和optionsValue直接allBindings,它會工作。這就是我所做的與你所描述的完全相同的場景。 – BrandonLWhite

回答

2

好的結合起來 - 我結束了使用申請綁定反正到節點:

ko.bindingHandlers.NamedIdOptions = 
{ 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) 
    { 
     var allBindings = allBindingsAccessor(); 
     var newBindingOptions = { options: allBindings.NamedIdOptions, optionsText: "Name", optionsValue: "ID" }; 

     delete allBindings.NamedIdOptions; 
     ko.utils.extend(newBindingOptions, allBindings); 

     ko.applyBindingsToNode(element, newBindingOptions, viewModel); 
    } 
}; 

而且它似乎按預期工作 - 我有點不確定價值和selectedOptions - 哪些有「後」設置爲選項。我想我在NamedIdOptions在值綁定之前鋪平了是安全的嗎?

+0

只有在刪除NamedIdOptions時纔會出現問題 - 實際上,所有已調用的操作都應該首先被刪除 –

1

轉發呼叫時,你不能只是假的allBindingsAccessor參數?

update: function (element, valueAccessor, allBindingsAccessor, viewModel) 
{ 
    var allBindings = allBindingsAccessor(), 
     fakeAllBindingsAccessor = function() { 
      // I've used jQuery.extend here, you could also manually add the properties to the allBindings object 
      return $.extend(true, allBindings, { 
       optionsValue: 'ID', 
       optionsText: 'Name' 
      }; 
     }; 
    return ko.bindingHandlers.options.init.call(this, element, valueAccessor, fakeAllBindingsAccessor, viewModel); 
} 

編輯:添加更多的代碼到現有allBindingsAccessor與手動假綁定

+0

這絕對是值得一試的 –

+0

不幸的是,它似乎並沒有工作。 可以在init函數中製作一個假的allbindings訪問器。在它的工作原理 - 然而,假更改覆蓋更新。 如果有人在更新方法中使用相同的技巧,則下列錯誤會得到以下錯誤: _'undefined'不是函數(評估'd.get(「optionsIncludeDestroyed」)')_ –

+0

您可以發佈完整你的HTML標籤的數據綁定?我會調試,看看我能否發現我的錯誤。 –

3

你可能會考慮使用ko.applyBindingAccessorsToNode。這就是我已經開始在KO 3.0做:

ko.bindingHandlers.NamedIdOptions = { 
    init: function(element, valueAccessor, allBindingsAccessor) 
    { 
     var injectedBindingValues = {   
      options: valueAccessor, 
      optionsValue: function() { return "ID" }, 
      optionsText: function() { return "Name" } 
     }; 

     ko.applyBindingAccessorsToNode(element, injectedBindingValues); 

     //tell Knockout that we have already handled binding the children of this element 
     // 
     return { controlsDescendantBindings: true };   
    } 
} 

你可以看到它在行動this fiddle

注意:我通常使用從服務器(C#,JSON.NET)發送的JSON模式自動從C#屬性或數據庫模式元數據中填充UI中的選項。我將我的代碼進行了提煉,並將其更改爲與OP針對問題的連續性所做的相匹配。但是如果對JSON模式技術有任何興趣,請打我併發布。

+0

Thx很多 - 顯然,它並沒有在我們使用的KO 2.2中定義在我們的生產環境中。但是,解決方案比我的上面要乾淨得多。 –

+0

關於服務器連接 - 我們保持我們的C#視圖模型儘可能小,並以Json格式自動序列化它們,並將它們轉換爲javasscript對象。因此,通常我們會沿着這樣的方式寫一些東西: '