【问题标题】:Create 2 way custom binding with observable plugin使用可观察插件创建 2 路自定义绑定
【发布时间】:2014-05-12 10:54:01
【问题描述】:

这个问题的线索似乎很难找到,我开始认为它要么很明显(而且我遗漏了一些东西),要么没用,要么不可能:

我在使用 observables (ko.observables()) 的淘汰赛中得到了 2-way binding 的东西。 然而,所有这些括号都是一个真正的痛苦。所以当我使用 Durandal 时,我想尝试一下 observableplugin:http://durandaljs.com/documentation/Binding-Plain-Javascript-Objects.html

(为了记录,我也试过这个:http://blog.stevensanderson.com/2013/05/20/knockout-es5-a-plugin-to-simplify-your-syntax/

在淘汰赛的valuebinding 上,两者都可以正常工作。

我的问题是我的应用程序有多个淘汰赛自定义绑定,我不知道如何更新这些自定义绑定中不是 ko.observable() 的可观察属性。

在我的绑定中,我通常会这样做:

ko.bindingHandlers.testBinding = {
    init: function(element, valueAccessor) {
        var myObservable = valueAccessor();
        // here I could detect if it's an observable or a POJO
        // ... how to know if it's a property ???

        $(element).blur(function() {

            // ... how to write to myObservable if it's a writable property
            // ... and not a ko.observable() ???
            myObservable($(element).val());

        });

    },
    update: function(element, valueAccessor) {
        $(element).val(ko.unwrap(valueAccessor()));
    }
};

但是对于可观察对象,我知道我需要对基础对象的引用和属性的 name 才能执行更新。 (我可以得到前者,但如何得到后者?)

我查看了淘汰赛的value 绑定以试图理解但没有更多成功...

有人能举一个简单的例子来说明使用 observable 插件会是什么样子吗? 任何线索将不胜感激。

谢谢

【问题讨论】:

  • “我不明白你如何更新不是 ko.observable() 的可观察属性” - 你能澄清一下吗?这很令人困惑。
  • 使用 ES5,您可以在具有 getter/setter 的 JS 对象上创建属性(因此是“可观察的”)。它们不是 ko.observable() 但仍然能够在没有括号混乱的情况下进行双向绑定。但是在 ko 自定义绑定中,我不知道如何写入此类属性。 (除自定义绑定外,它适用于其他任何地方)

标签: knockout.js durandal


【解决方案1】:

使用 Knockout 的preprocess feature,您的绑定可以添加一个方法来直接写入属性。你可以这样做:

ko.bindingHandlers.testBinding = {
    preprocess: function(value, name, addBindingCallback) {
        addBindingCallback('testBindingWriter', 'function(v){' + value + ' = v}');
        return value;
    },
    init: function(element, valueAccessor, allBindings) {
        var value = valueAccessor();
        $(element).blur(function() {
            if (ko.isObservable(value)) {
                value($(element).val());
            } else {
                allBindings.get('testBindingWriter')($(element).val());
            }
        });
    },
    update: function(element, valueAccessor) {
        $(element).val(ko.unwrap(valueAccessor()));
    }
};

示例:http://jsfiddle.net/mbest/U7Jeg/

【讨论】:

    【解决方案2】:

    如果您只想获取属性名称,您可以使用预处理将其存储在绑定处理程序中,如下所示:

    propertyName: null,
    preprocess: (value) => {
            this.propertyName = value;
            return value;
    },
    

    您现在可以在 init 函数中访问该属性并将其与 bindingContext 结合以设置值:

    init: (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) => {
            $(element).blur(() => {
                bindingContext.$data[this.propertyName] = $(element).val();
            })
    }
    

    注意:我使用上面的箭头函数来保留“this”的含义。如果这不是一个选项,您可以这样做:

    init: (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) => {
            thisHandler = this;
            $(element).blur(function () {
                bindingContext.$data[thisHandler.propertyName] = $(element).val();
            })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-08
      • 2011-04-25
      • 2012-11-02
      • 2018-11-06
      • 2011-12-20
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      相关资源
      最近更新 更多