5

バインドされたスパンがあるとしましょう

<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>
4

6 に答える 6

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は危険な関数ですが、式を文字列として使用することはできます。eval()サンプルのJSFiddleを次に示します。

Child.Nameまたは、ドットで文字列を分割し、アクセサーで foreach を分割する独自のパーサーを作成できるように、単純なプロパティ式のみをサポートする必要がある場合。

于 2013-01-16T06:46:06.603 に答える
2

実際、Knockoutにこれを行う組み込みの方法があります。カスタム バインディングを少し調整する必要があります (つまり、文字列値ではなくオブジェクトになります)。Knockout を使用すると、initおよびupdateプロパティとともに、プロパティを指定でき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 つのキー (ここでは名前と値) を持つオブジェクトに変換するだけです。見てください。詳細については、バインディングの前処理を参照してください。

于 2015-06-07T16:28:53.160 に答える
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()は、ビューモデルの最も深いレベルにあるため、呼び出して戻り値を使用して html を更新できます。

于 2015-06-04T10:15:59.937 に答える
1

上記のパベル・チェルボフの言葉が好きです。同様に、少し 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');
    },
};
于 2016-04-22T02:36:51.273 に答える
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" になります。

于 2016-02-12T19:26:20.740 に答える