2013-01-16 19 views
6

可以說我有一個綁定範圍如何獲得在淘汰賽的JS BindingHandler內的綁定表達式

<span data-bind="MyBinding: Name"></span> 

而且我有一個自定義綁定

ko.bindingHandlers.MyBinding = { 
    init: function (element, valueAccessor, allBindings, viewModel, context) { 
     // I want to get the string "Name" here. NOT the value of Name. 
    }, 
}; 

我如何得到一個字符串與處理程序內綁定表達式的值?即我如何得到「名稱」而不是「名稱的價值」。

我還需要表達式,因此傳遞字符串「名稱」是不可行的。

<span data-bind="MyBinding: 'Name'"></span> 

回答

2

其實,敲除確實有一個內置的方式來做到這一點。你需要適應你的自定義綁定一點(即,它變成一個對象而不是字符串值)。 Knockout允許您與initupdate屬性一起指定preprocess屬性。例如,假設我們有以下視圖模型:

var app = { data: ko.observable('Hello World') }; 

和一個簡單的結合,將轉換傳遞給它充分小寫的字符串,並輸出兩裝訂的名稱和值(在視圖中傳遞的性質顯然是data):

ko.bindingHandlers.lower = { 
    update: function(elem, value) { 
    var obj = ko.unwrap(value()); 
    elem.textContent = 'Name: ' + ko.unwrap(obj.name) + 
     ' - Value: ' + ko.unwrap(obj.data).toLowerCase(); 
    }, 
    preprocess: function(value, bindingName) { 
    return '{data:' + value + ', name:\'' + bindingName + '\'}'; 
    } 
}; 

它作爲字符串化的value屬性傳遞給它&改造結合的價值與2個鍵(名字&值這裏)一個對象一樣簡單。 Have a look。有關更多信息,請參閱Binding preprocessing

2

您需要Name傳遞的字符串,而不是作爲一個參考:

<span data-bind="MyBinding: 'Name'"></span> 

ko.bindingHandlers.MyBinding = { 
    init: function (element, valueAccessor, allBindings, viewModel, context) { 
     var myBinding = valueAccessor(); // will contain 'Name'; 
     var valueOfmyBinding = viewModel[myBinding]; //value of the Name property 
    }, 
}; 

你仍然可以使用你的表達式作爲一個字符串,因爲在Javascript中你可以eval altough eval()是一個危險的函數:這裏是一個樣本JSFiddle

或者,如果您只需要支持簡單的屬性表達式,如Child.Name,則可以編寫自己的解析器,將字符串拆分爲點和foreach上的訪問器。

+0

如果它是一個複雜的表達式,它將如何工作。例如「Child.Name」 – Simon

+0

爲什麼字符串不適合你?在JavaScript中,你可以基本上將任何字符串評估爲JS代碼。 – nemesv

+0

當然。讓我嘗試。 – Simon

1

你可以做以下事情,所以你不需要評估。

<span data-bind="MyBinding: 'Name.More.AndMore'"></span> 

ko.bindingHandlers.MyBinding = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     var value = valueAccessor(); 

     var sp = value.split('.'); 
     var current = viewModel; 
     for(var i=0;i<sp.length;i++) { 
      var nNode = current[sp[i]]; 
      if (nNode) { 
       current = nNode; 
      } 
     } 
     $(element).html(current()); 
    } 
}; 

由於已經解釋的,你需要給名稱爲字符串值在你的綁定。之後,您可以使用它來逐步瀏覽您的視圖模型以檢索值。要顯示我添加的元素中的值 $(element).html(current()); 這裏current()在我的viewmodel中處於最深層次,因此可以調用它,並且可以使用返回值來更新html。

+0

你能描述一下「以下」是什麼嗎?它爲什麼回答這個問題?您可以[編輯]您的答案以包含說明。 –

+0

我只是擴大了@nemesv給出的答案。通過以下我的意思是下面的一段代碼 – gkempkens

0

我有點晚在此聚會,但這裏是我做到了,它就像一個魅力:

JS:

ko.bindingHandlers.myHandler = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var regex = /return ([^\s]+)\s*}/; 

     //accessor will contain whatever expression was used in data-bind 
     //so in this example it will be "myProp.childProp" 
     var accessor = regex.exec(valueAccessor.toString())[1]; 

     //... 
}, 
//... 

HTML:

<div data-bind="myHandler: myProp.childProp"></div> 

所以訪問者的價值(如果你錯過了評論)將是「myProp.childProp」

1

我建議將專家的名字使用另一個綁定。

<div data-bind="myBinding: content, nameOfProp:'content'"></div> 

ko.bindingHandlers.myBinding = { 
    init: function(element, valueAccessor, allBindings, viewModel, context) { 
     var nameOfProp = allBindings.get("nameOfProp"); 
    }; 
    } 

JSFiddle

1

我喜歡什麼帕維爾 - chervov上面說的。如果你不介意使用一些jQuery,可以採用類似的方式:

<span data-binding-name="Name" data-bind="MyBinding: Name"></span> 

ko.bindingHandlers.MyBinding = { 
    init: function (element, valueAccessor, allBindings, viewModel, context) { 
     var nameOfProp = $(element).data('binding-name'); 
    }, 
};