【问题标题】:How to update custom binding on button click?如何在按钮单击时更新自定义绑定?
【发布时间】:2015-12-09 17:52:59
【问题描述】:

通过单击按钮,我想根据两个选择元素的值更新 d3js 图。如果我理解正确,只需调用 valueAccessor 即可触发更新功能,这在我的代码中没有发生。

我有以下自定义绑定:

ko.bindingHandlers.plotSvg = {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        valueAccessor();
        console.log("Update d3js plot");
    }
};

还有观点:

    <div class="panel-body">
        <div class="row">
            <div class="col-xs-2">
                <select class="form-control"
                        data-bind="options: $root.options,
                                           optionsText: 'name',
                                           value: firstSelectedOption">
                </select>
            </div>
            <div class="col-xs-2">
                <select class="form-control"
                        data-bind="options: $root.options,
                                           optionsText: 'name',
                                           value: secondSelectedOption">
                </select>
            </div>
            <div class="col-xs-2 col-xs-offset-5">
                <button class="btn btn-primary" data-bind="click: updatePlot">
                    Visualise
                </button>
            </div>
        </div>
        <div data-bind="plotSvg: updatePlot"></div>
    </div>

updatePlot 是视图模型中的一个函数,它所做的只是在此刻打印一个值。

编辑 javascript:http://pastebin.com/2qKLf6yf 观点:http://pastebin.com/TPvmKgxL

【问题讨论】:

    标签: knockout.js custom-binding


    【解决方案1】:

    &lt;div data-bind="plotSvg: updatePlot"&gt;&lt;/div&gt; 需要引用一个计算值,否则敲除将不知道某些东西的值何时发生了变化,因此永远不会触发自定义绑定的更新方法。

    我会推荐类似的东西:

    &lt;div data-bind="plotSvg: selectedValue"&gt;&lt;/div&gt;

    ko.bindingHandlers.plotSvg = {
        update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            viewModel.redrawPlot();
            console.log("Update d3js plot");
        }
    };
    

    其中selectedValue 是一个计算,它跟踪表单上当前选定的值,并在单击按钮时更新。

    由于您使用两个值,您可以在 viewModel 中执行类似的操作来触发可观察到的更改:

    this.selectedValue = ko.observable(null);
    this.updatePlot = function(){
        this.selectedValue(this.firstSelectedOption()+""+this.secondSelectedOption()+"")
    }
    

    这样做将确保每次选项之一更改时它都是唯一的字符串。如果两者都没有改变,那么 observable 不会改变,并且情节不应该重绘。它的蛮力,但它应该适用于您的设置。

    【讨论】:

    • 这意味着情节将在选择更改时更新,这是我不想要的。我想通过单击一个按钮来更新绘图。
    • 老实说,很难说到底在情节上使用了什么=)您可以在按钮单击而不是选择更改时使selectedValue 更改.. 它只是一个可观察的。我将在上面更新一个示例
    • 您可以在单击按钮时更改 selectedValue 而不是选择更改 啊!那行得通。感谢您的出色解决方案!
    【解决方案2】:

    当您调用valueAccessor() 时,您只会得到访问器的值,所以要调用函数试试这个:valueAccessor()()

    • valueAccessor — 一个 JavaScript 函数,您可以调用它来获取此绑定中涉及的当前模型属性。在不传递任何参数的情况下调用它(即调用 valueAccessor())以获取当前模型属性值。要轻松接受可观察值和普通值,请在返回值上调用 ko.unwrap。

    参考。 http://knockoutjs.com/documentation/custom-bindings.html

    【讨论】:

    • 不幸的是,这不起作用。我将valueAccessor()()ko.unwrap(valueAccessor()) 都绑定了
    • 您需要确保updatePlot 在正确的上下文中并且具有任何值。尝试console.log(valueAccessor())
    • 它返回正确的值:函数updatePlot
    • 嗯...所以只是为了测试尝试valueAccessor.bind(bindingContext)();,当我不知道视图模型时很难; XD
    • 返回正确的值,但没有更新。也许 update 仅在 valueAccessor 是可观察的时才被触发? updatePlot 只是一个普通函数
    猜你喜欢
    • 2015-05-26
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多