在选择改变的事件有约束力的淘汰赛,我怎么能知道它真正的变化(change event on sele

2019-07-30 00:25发布

我建立一个许可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不会在所有情况下帮助,为什么?因为在大多数的模式会是这样实现的

  1. 初始化与未定义的数据模型,只是结构(actual KO initilization)
  2. 更新初始数据模型(logical init like load JSON , get data etc)
  3. 用户交互和更新

我们想捕捉的实际步骤是在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
标签: knockout.js