我建立一个许可UI,我有权与相邻的许可选择列表清单。 的权限由被绑定到选择列表对象的可观察到的阵列表示:
<div data-bind="foreach: permissions">
<div class="permission_row">
<span data-bind="text: name"></span>
<select data-bind="value: level, event:{ change: $parent.permissionChanged}">
<option value="0"></option>
<option value="1">R</option>
<option value="2">RW</option>
</select>
</div>
</div>
现在的问题是这样的:改变事件被当UI只是填充首次提出。 我把我的AJAX功能,获得的权限列表,然后将事件引起人们的关注每一许可项目。 这真的不是我想要的行为。 我希望它被提出,只有当用户真正挑选出在选择列表中的权限的新的价值 ,我该怎么办呢?
Answer 1:
其实你要查找的事件是否是由用户或程序触发的,其明显的事件触发而初始化。
加入的淘汰赛方式subscription
不会在所有情况下帮助,为什么?因为在大多数的模式会是这样实现的
- 初始化与未定义的数据模型,只是结构
(actual KO initilization)
- 更新初始数据模型
(logical init like load JSON , get data etc)
- 用户交互和更新
我们想捕捉的实际步骤是在3个变化,但在第二个步骤subscription
将得到调用,因此更好的办法是增加类似事件的变化
<select data-bind="value: level, event:{ change: $parent.permissionChanged}">
和检测到的在事件permissionChanged
功能
this.permissionChanged = function (obj, event) {
if (event.originalEvent) { //user changed
} else { // program changed
}
}
Answer 2:
这只是一个猜测,但我认为它的发生是因为level
是多少。 在这种情况下,该value
绑定将触发change
的事件来更新level
与字符串值。 你可以解决这个问题,因此,通过确保level
是开始的字符串。
此外,这样做的更多的“淘汰赛”的方法是不使用事件处理程序,而是利用观测和订阅。 制作level
可观察到的,然后添加订阅它,这将让运行时level
的变化。
Answer 3:
这里是一个解决方案,它可以用这种奇怪的行为提供帮助。 我找不到比放置一个按钮来手动触发事件改变一个更好的解决方案。
编辑:也许一个自定义的这样的结合可以帮助:
ko.bindingHandlers.changeSelectValue = {
init: function(element,valueAccessor){
$(element).change(function(){
var value = $(element).val();
if($(element).is(":focus")){
//Do whatever you want with the new value
}
});
}
};
而在你选择数据绑定属性添加:
changeSelectValue: yourSelectValue
Answer 4:
我用这个自定义绑定(基于此琴由RP尼迈耶,看他的回答这个问题),这可以确保数值正确的字符串转换为数字(由麦可思的解决方案的建议):
使用Javascript:
ko.bindingHandlers.valueAsNumber = {
init: function (element, valueAccessor, allBindingsAccessor) {
var observable = valueAccessor(),
interceptor = ko.computed({
read: function () {
var val = ko.utils.unwrapObservable(observable);
return (observable() ? observable().toString() : observable());
},
write: function (newValue) {
observable(newValue ? parseInt(newValue, 10) : newValue);
},
owner: this
});
ko.applyBindingsToNode(element, { value: interceptor });
}
};
例如HTML:
<select data-bind="valueAsNumber: level, event:{ change: $parent.permissionChanged }">
<option value="0"></option>
<option value="1">R</option>
<option value="2">RW</option>
</select>
Answer 5:
如果您使用的不是原始值可观察到的,选择不会提高对初始绑定变化事件。 您可以继续绑定到更改事件,而不是直接订阅可观察的。
Answer 6:
快速和肮脏的,利用一个简单的标志:
var bindingsApplied = false;
var ViewModel = function() {
// ...
this.permissionChanged = function() {
// ignore, if flag not set
if (!flag) return;
// ...
};
};
ko.applyBindings(new ViewModel());
bindingsApplied = true; // done with the initial population, set flag to true
如果这不起作用,尝试包的最后一行中的setTimeout() - 事件是异步,所以也许是最后一个仍悬而未决时applyBindings()已退回。
Answer 7:
我有一个类似的问题,我只是修改了事件处理程序来检查变量的类型。 用户选择了一个值之后,而不是当在第一次加载的页面的类型仅设定。
self.permissionChanged = function (l) {
if (typeof l != 'undefined') {
...
}
}
这似乎为我工作。
Answer 8:
用这个:
this.permissionChanged = function (obj, event) {
if (event.type != "load") {
}
}
Answer 9:
如果使用的是淘汰赛工作,使用可观察到的功能基因敲除的关键功能。
使用ko.computed()
方法和函数中做,触发Ajax调用。
文章来源: change event on select with knockout binding, how can i know if its a real change