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.
   },
};

如何在处理程序中获取具有绑定表达式值的字符串?即我如何获得“名称”而不是“名称的值”。

我还需要表达式,因此传递字符串“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 中您可以评估 alougheval()是一个危险的函数:这​​里是一个示例JSFiddle 。

或者,如果您只需要支持简单的属性表达式,例如Child.Name您可以编写自己的解析器,在其中拆分点上的字符串并在访问器上进行 foreach。

于 2013-01-16T06:46:06.603 回答
2

实际上,Knockout确实有一个内置的方法来做到这一点。您确实需要稍微调整您的自定义绑定(即,它变成一个对象而不是字符串值)。Knockout 允许您与initupdate属性一起指定preprocess属性。例如,假设我们有以下 viewModel:

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());
    }
};

正如已经解释的那样,您需要在绑定中将 Name 作为字符串值提供。之后,您可以使用它来逐步浏览您的视图模型以检索值。在我添加的元素中显示值 $(element).html(current()); 这里current()是在我的视图模型中的最深层次,因此可以调用它并且可以使用返回值来更新 html。

于 2015-06-04T10:15:59.937 回答
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

于 2016-04-01T15:35:02.753 回答
1

我喜欢上面说的pavel-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');
    },
};
于 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 回答