Ajax 将KnockoutJS与jqueryui微调器一起使用

Ajax 将KnockoutJS与jqueryui微调器一起使用,ajax,data-binding,knockout.js,durandal,Ajax,Data Binding,Knockout.js,Durandal,我现在正在使用jQueryUI的微调器和KnockoutJS和Durandal。我遵循了答案/例子 创建一个自定义绑定,负责初始化微调器并观察对微调器所做的更改 现在,我已经将其保存为一个公共模块,加载到lib文件夹中,由将来需要使用微调器的模块调用。我这里的问题是,在这个特定的页面上,我想检索微调器的值/在每次微调器更新时进行ajax调用,从而更新数量。我知道我不可能将自定义ajax代码放在公共模块中,但我不知道该放在哪里 下面是进行数据绑定的HTML: <p class="qty"&g

我现在正在使用jQueryUI的微调器和KnockoutJS和Durandal。我遵循了答案/例子 创建一个自定义绑定,负责初始化微调器并观察对微调器所做的更改

现在,我已经将其保存为一个公共模块,加载到lib文件夹中,由将来需要使用微调器的模块调用。我这里的问题是,在这个特定的页面上,我想检索微调器的值/在每次微调器更新时进行ajax调用,从而更新数量。我知道我不可能将自定义ajax代码放在公共模块中,但我不知道该放在哪里

下面是进行数据绑定的HTML:

<p class="qty">
    <input class="spinner" data-bind="spinner: quantity, spinnerOptions: { min: 1, numberFormat: 'n' }" />
    <a class="remove" href="#">Remove</a>
</p>
以下是我基于上述链接构建的通用模块:

define(function(require) {

    var system = require('durandal/system'),
    app = require('durandal/app'),
    ko = require('knockout');

    ko.bindingHandlers.spinner = {

    init: function(element, valueAccessor, allBindingsAccessor) {

        //initialize datepicker with some optional options
            var options = allBindingsAccessor().spinnerOptions || {};
            $(element).spinner(options);

            //handle the field changing
            ko.utils.registerEventHandler(element, 'spinchange', function () {
        var observable = valueAccessor();
        observable($(element).spinner('value'));
            });

            //handle disposal (if KO removes by the template binding)
            ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
        $(element).spinner('destroy');
            });

    },

    update: function(element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor()),
        current = $(element).spinner('value'),
        msg = 'You have entered an Invalid Quantity. \n Please enter at least 1 or remove this item if you do not want to include it in the shopping cart.';

        system.log(value);

        if(isNaN(parseInt(value))) {
        alert(msg);
        }

            if (value !== current && !isNaN(parseInt(value))) {
        $(element).spinner("value", value);
            }
    }
    };

});
据我所知,我应该有类似于
data bind=“value:quantity,click:updatequality”
的功能,以便在可观察的数量发生变化时调用updatequality函数。然而,现在我正在使用spinner自定义绑定,我不再确定如何调用updateQuantity函数。每个更改都将由公共模块中的代码捕获(如Chrome inspector中的system.log所示),但在我的page.js中,我不知道在哪里以及如何调用捕获ajax调用中使用的新数量的函数


我意识到我对KnockoutJS和数据绑定的理解还很模糊(几周前才开始),所以如果有人能告诉我应该从这里走到哪里,我将非常高兴。先谢谢你

进行AJAX调用和微调器之间没有任何关系。下面,我向您展示了我们是如何做到这一点的,但是使用了SpinJS。尽管图书馆不同,校长还是一样的

以下是微调器的自定义绑定:

ko.bindingHandlers.spinner = {
            init: function(element, valueAccessor) {
                var options = ko.unwrap(valueAccessor());

                var opts = {
                    lines: options .lines || 8,
                    length: options .length || 3,
                    width: options .width || 4,
                    radius: options .radius || 6,
                    color: options .color || '#FFF',
                    speed: options .speed || 1,
                    trail: options .trail || 100,
                    shadow: options .shadow == undefined ? false : value.shadow,
                    zIndex: options .zIndex || 2000
                };

                var spinner = new Spinner(opts).stop();
                $(element).data(element.id, spinner);
            },

            update: function(element, valueAccessor) {
                var options = ko.unwrap(valueAccessor()),

                    isSpinning = options .isSpinning,
                    positioning = options .positioning || 'manual',

                    spinner = $(element).data(element.id);

                if (isSpinning) {
                    if (positioning == 'manual') {
                        spinner.spin();
                        $(element)[0].appendChild(spinner.el);
                    } else if (positioning == 'auto') {
                        spinner.spin(element);
                    }
                } else {
                    spinner.stop();
                }
            }
以下是使用自定义绑定的视图:

<div data-bind="visible: isFetchingOpportunities()">
    <div id="activitySpinner" class="ts-ajax-spinner" data-bind="spinner: { isSpinning: isFetchingOpportunities() }">
    </div>
</div>
现在,我们已经将AJAX调用封装到一个数据服务中,该服务反过来利用了JS。但是,原则是一样的。您也可以轻松地直接进行AJAX调用


这有意义吗

如果我理解正确,我认为您所需要做的就是订阅可观察的数量,并在该函数中使用进行ajax调用。比如:-

注意:我将
ko.utils.registerEventHandler
spinchange
更改为
spinstop

ko.bindingHandlers.spinner={
init:function(元素、valueAccessor、allBindingsAccessor){
//使用一些可选选项初始化日期选择器
var options=allBindingsAccessor().spinnerOptions | |{};
$(元素).微调器(选项);
//处理字段更改
registerEventHandler(元素'spinstop',函数(){
var可观测=valueAccessor();
可观察($(元素).spinner('value');
});
//处理处置(如果KO通过模板绑定移除)
ko.utils.domNodeDisposal.addDisposeCallback(元素,函数(){
$(元素).spinner('destroy');
});
},
更新:函数(元素、值访问器){
var value=ko.utils.unwrapobbservable(valueAccessor()),
当前=$(元素).spinner('value'),
msg='您输入的数量无效。\n如果不想将此项目包括在购物车中,请至少输入1或删除此项目。';
if(isNaN(parseInt(值))){
警报(msg);
}
if(value!==current&&!isNaN(parseInt(value))){
$(元素)。微调器(“值”,值);
}
}
};
var Vm=函数(){
var self=这个;
自身数量=可观察的ko(0);
self.quantity.subscribe(更新数据);
函数updateData(newValue){
//你在这里打电话吗
警报(新值);
}
回归自我;
};
应用绑定(新Vm())


我不确定这是否有帮助,但是如果您可以从自定义微调器绑定的更新回调函数中访问ViewModel的绑定上下文,并且
updateQuantity()
函数在ViewModel中,那么我看不出您不能调用
updateQuantity()的原因
。谢谢你的帮助。使用ISSpining作为要在自定义绑定中检查的选项很有趣。但我不能真正理解你们的第二部分,那个是什么时候,那个么,那个么。最后我使用
通过allBindings调用回调。不客气。是的,我们的
dataservice
返回一个承诺,当AJAX调用(我们的restapi)返回时,这个承诺就会得到解决。这就是触发
然后
的原因。换句话说,微调器一直旋转,直到AJAX调用解决为止,此时旋转设置为
false
。感谢您的回复。Subscribe看起来是一个很有趣的功能——我这次没有使用它,但它将来可能会派上用场。
<div data-bind="visible: isFetchingOpportunities()">
    <div id="activitySpinner" class="ts-ajax-spinner" data-bind="spinner: { isSpinning: isFetchingOpportunities() }">
    </div>
</div>
this.isFetchingOpportunities(true);
var that = this;
$.when(dataservice.getData(options, getFunction, modelmapper.opportunity))
     .then(function() {
         that.isFetchingOpportunities(false);
     });