假设我有一个限制范围
<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>
答案 0 :(得分: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
这样的简单属性表达式,那么您可以编写自己的解析器,将字符串拆分为点,并在访问器上进行操作。
答案 1 :(得分:2)
实际上,Knockout 有一个内置的方法来做到这一点。您需要稍微调整自定义绑定(即,它变为对象而不是字符串值)。 Knockout允许您与init
和update
属性一起指定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
属性一样简单&amp;将绑定的值转换为具有2个键的对象(此处为name&amp; value)。 Have a look。有关详细信息,请参阅Binding preprocessing。
答案 2 :(得分:1)
您可以执行以下操作,因此您不会需要eval。
auto& objects = group->getObjects();
for (auto &obj : objects) {
auto &properties = obj.asValueMap();
cc_log(properties["type"].asString());
}
正如nemesv已经解释过的那样,您需要在绑定中将Name作为字符串值。之后,您可以使用它来逐步浏览viewmodel以检索值。要在我添加的元素中显示值
<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());
位于我的viewmodel中最深层,因此可以调用它,返回值可用于更新html。
答案 3 :(得分:1)
我建议使用另一个绑定来转移属性的名称。
<div data-bind="myBinding: content, nameOfProp:'content'"></div>
ko.bindingHandlers.myBinding = {
init: function(element, valueAccessor, allBindings, viewModel, context) {
var nameOfProp = allBindings.get("nameOfProp");
};
}
答案 4 :(得分: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');
},
};
答案 5 :(得分:0)
I'm a bit late to the party on this, but here's what I did, and it works like a charm:
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>
So the value of accessor (in case you missed the comment) will be "myProp.childProp"