2013-01-16 15 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. 
    }, 
}; 

をカスタムバインディングを持っていますハンドラ内のバインディング式の値?私はどのように "名前の価値"ではなく "名前"を得るのですか?

"Name"という文字列を渡すことも可能です。あなたは文字列としてではなく参考としてNameに渡す必要があり

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

答えて

2

実際には、ノックアウトにはにはこれを行うための組み込み方法があります。カスタムバインディングを少し変更する必要があります(つまり、文字列値ではなくオブジェクトになります)。 Knockoutでは、initupdateのプロパティに加えて、preprocessプロパティを指定することができます。明らかにされて

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

、完全に小文字に渡された文字列を変換することを単純な結合、および出力の両方のバインディングの名前と値(ビューに渡されたプロパティ:たとえば、私たちは次のViewModelを持っていると仮定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 + '\'}'; 
    } 
}; 

これは、2つのキー(ここでは名前&値)を持つオブジェクトへのバインディング値を変換&それに渡されたvalueプロパティを文字列化と同じくらい簡単です。 Have a look。詳細は、Binding preprocessingを参照してください。

2

<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コードに 'evalすることができます。もちろん、 – nemesv

+0

。私が試してみましょう。 – Simon

1

あなたは以下のことができるので、評価は必要ありません。

すでに説明したように、名前をバインディングの文字列値として指定する必要があります。その後、これを使用してviewmodelをステップ実行して値を取得できます。要素に値を表示するには $(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

私はプロの名前を転送することを提案しますpertyは別のバインディングを使用します。

<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'); 
    }, 
}; 
関連する問題