0

我目前正在使用Bing Maps KO自定义绑定,以便在 Durandal 中轻松轻松地使用 Bing Maps 控件。

到目前为止,我已经扩展了自定义绑定以允许使用信息框,并且工作正常,因为我只需在视图模型中设置可观察对象的值并更新信息框。

现在我希望能够在自定义绑定中包含的地图对象之一上调用函数。

我希望将地图缩放到特定点。请注意,我不想设置地图中心点,但我希望调用将处理地图动画到该点的函数。

这可以通过在视图模型中设置一个可观察字段来实现,然后自定义绑定调用它的更新函数,它获取值,调用方法,然后将可观察对象重置为空。

这感觉相当 hacky 但应该可以工作,并且它并没有真正超出使用 MVVM 时应该保持的分隔线。

是否有另一种方法可以使用函数语法来实现这一点,以便更准确地描述正在发生的事情。(我要求执行一系列操作,而不是设置一个值。)

4

1 回答 1

0

实现此目的的一种方法是使用事件。

您可以向自定义绑定传递事件名称并让它订阅该事件。

由于我使用的是 Durandal,我通常会使用内置事件系统,但 jsFiddle 只有 KnockoutJS 可用,因此以下示例使用了一个小型PubSub 库

这是示例代码,而不是任何将投入生产的东西。

jsFiddle

//PubSub//
(function(a,c,b){if(typeof module!=="undefined"){module.exports=b(a,c)}else{if(typeof define==="function"&&typeof define.amd==="object"){define(b)}else{c[a]=b(a,c)}}})("radio",this,function(b,c){function a(d){a.$.channel(d);return a.$}a.$={version:"0.2",channelName:"",channels:[],broadcast:function(){var f,j=this.channels[this.channelName],d=j.length,g,h,e;for(f=0;f<d;f++){g=j[f];if((typeof(g)==="object")&&(g.length)){h=g[0];e=g[1]||c}h.apply(e,arguments)}return this},channel:function(d){var e=this.channels;if(!e[d]){e[d]=[]}this.channelName=d;return this},subscribe:function(){var f=arguments,j=this.channels[this.channelName],g,e=f.length,h,d=[];for(g=0;g<e;g++){d=f[g];h=(typeof(d)==="function")?[d]:d;if((typeof(h)==="object")&&(h.length)){j.push(h)}}return this},unsubscribe:function(){var g=arguments,k,h,n=this.channels[this.channelName],f=g.length,e=n.length,m=0,d;for(k=0;k<f;k++){m=0;e=n.length;for(h=0;h<e;h++){d=h-m;if(n[d][0]===g[k]){n.splice(d,1);m++}}}return this}};return a});
//PubSub//

ko.bindingHandlers.customBinding = {
    _textBoxes: {},
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var _valueAccessor = valueAccessor();

        var textBox = document.createElement("input");
        textBox.type = "text";
        element.appendChild(textBox);

        ko.bindingHandlers.customBinding._textBoxes[element.id] = textBox;

        if(_valueAccessor.clearEventName) {
            radio(_valueAccessor.clearEventName).subscribe(function() {
                _valueAccessor.text("");
            });
        }

        if(_valueAccessor.text) {
            textBox.onchange=function() { _valueAccessor.text(textBox.value); };
        }
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var _valueAccessor = valueAccessor();

        if(_valueAccessor.text) {
            ko.bindingHandlers.customBinding._textBoxes[element.id].value = _valueAccessor.text();
        }
    }
};

var viewModel = {
    text: ko.observable("Inital value."),
    doClear: function() {
        radio('clear').broadcast();
    },
    doReset: function() {
        viewModel.text("Reset value.");
    }
};

ko.applyBindings(viewModel);
于 2013-10-26T10:10:27.870 回答