我想使用Ractivejs实现简单的切换按钮功能。这是代码:

function MyViewModel(model) {
    var self = this;
    self.value = false;
    self.toggleValue = function () {
        self.value = !self.value; //this will probably not update view, but it is not the point here
    };
}

var viewModel = new MyViewModel(model);
var ractive = new Ractive({ el: 'mydiv', template: '#mytemplate', data: viewModel });


这是我的模板

<script id='mytemplate' type='text/ractive'>
    <p>Value: {{value}}</p>
    <button type="button">Toggle</button>
</script>


单击按钮时如何调用MyViewModel.toggleValue函数?现在,我知道两个选择:


我可以将on-click='toggle("value")'添加到button元素。但是,假设我的toggleValue函数可能稍微复杂一些,所以这种解决方案还不够。
我可以将on-click='toggleValue'添加到button元素。但是然后我需要添加以下代码:

ractive.on('toggleValue',function(){
    viewModel.toggleValue();
});


意思就是:


我正在编写必须在此视图模型之外了解我的视图模型的代码。从封装的角度来看,这是不好的。
这也意味着toggleValue对于Ractive实例是全局的,并且不查看特定于模型的模型,这意味着迟早会出现维护问题。
它绝不比使用jQuery $("button").click(myFunction)好。


那我该怎么做呢?我需要KnockoutJs的data-bind="click: toggleValue"

编辑:对于工作代码请看这里:http://jsfiddle.net/xak5k8rd/

最佳答案

您可以通过向Ractive添加原型方法来创建该类型的语法:

Ractive.prototype.bind = function(context, method){

    // if using < 0.6.1 you may encounter bug {{this}} or {{.}} not returning model root
    //context = context || this.data

    context[method].call(context, this)
}


然后在您的模板中使用:

<button type="button" on-click="bind(this, 'toggleValue')">Toggle</button>
<ul>
{{#tab}}
    <li on-click="bind(this, 'click')">{{val}}</li>
{{/tab}}
</ul>


http://jsfiddle.net/obdk4k2o/2/

编辑:添加了绑定功能的上下文。请注意,可以传递任何模板模型值,但是this对于列表肯定很方便。

编辑:在0.6.1中,方法调用可以访问this.event,这意味着键路径以及上下文都是可用的(因此不需要传递)。

该方法变为:

Ractive.prototype.bind = function(method){
    var context = this.event.context,
        keypath = this.event.keypath
    context[method].call(context, this, keypath)
}


模板是:

<button type="button" on-click="bind('toggleValue')">Toggle</button>
<ul>
{{#tab}}
    <li on-click="bind('click')">{{val}}</li>
{{/tab}}
</ul>


在您的视图模型中:

self.click=function(ractive, keypath){
    ractive.set(keypath + ".val", !self.val);
    alert('click');
}


http://jsfiddle.net/obdk4k2o/6/

10-08 00:14