麻烦覆盖对象/类的toString

时间:2014-10-07 00:13:13

标签: javascript jquery json forms backbone.js

正如标题所说,我试图在使用backbone-forms构建的表单中实现一些条件显示逻辑。该环境还使用Backbone.js,Underscore.js和jQuery。

我在SO" backbone-forms with conditional fields"上已经回顾了类似的问题,但是我们的用例有点不同:我们的字段依赖于多个条件(例如,只有foo =才显示1和bar = 2)。

[编辑:我已经编写了一个通用的表单更改事件处理程序来处理隐藏和显示不同的字段,因此我不想要有关该部分的建议。] < / p>

我试图使用数据属性来包含字段条件的JSON表示,但我对其他解决方案持开放态度。这大致是我目前正在努力实现的目标:

<input id="field3" name="field3" data-conditional-conditions='{"field1":"yes","field2":"yes"}' type="text">

我发现骨干表单使用jQuery的attr()方法来设置模型schemahere's the relevant line in backbone-forms' source)中指定的任何属性,并且似乎attr()反过来使用Object.prototype.toString()在渲染编辑器时将对象表示为值。*

所以我一直在努力实现一个Conditions对象,如下所示:

var Conditions = function(args){

    c = {
        toString: function(){
            return(JSON.stringify( _.omit(this, _.functions(this)) ));
        }
    };

    c.toString = _.bind(c.toString, c); //makes 'this' refer to the 'c' object

    args = _.isObject(args) ? args : {}; //default value for args

    c = _.defaults(c, args); //sets object key/value pairs from arguments

    return c;
};

我上面的目标是将toString()方法替换为将返回对象的JSON格式表示的方法,而不必修改主干表单。

不幸的是,上述内容并不常用,因为表单字段如下所示:

<input id="field3" name="field3" tostring="{"data-conditional-conditions":{"field1":"yes","field2":"yes"}}" data-conditional-conditions="[object Object]" type="text">

我已经达到了JavaScript知识的最终目标,并对所发生的事情感到沮丧。我尝试过使用IIFE并从我的条件函数中返回c.toString,但这些都没有用。

感谢阅读,我期待着您的建议!

*:我推断了这一点,因为如果我致电attr({"data-key": {"foo": "bar"} }),结果会显示为<div data-key="[object Object]">

2 个答案:

答案 0 :(得分:1)

这是一个意见问题,但我首先要问问自己这些条件是否属于属性。这是我讨厌AngularJS哲学的一个原因 - 在视图中有太多该死的逻辑。抛开所有哲学......

在另一个SO线程中,代码示例中包含以下内容:

 form.on('inputType:change', function(form, editor) {         
    form.fields['line'].$el.toggle();
    form.fields['area'].$el.toggle();
});

你可以做的一件事,虽然可能有一个更清洁的重构应用(我不太了解骨干形式),如下:

// Hide field 3.
form.fields['field3'].$el.hide();

function shouldShowField3(form) {
  return (form.fields['field1'].getValue() == 'yes' && form.fields['field2'].getValue() == 'yes')
}

function toggleField3(form, events) {
  if shouldShowField3(form) {
    form.fields['field3'].show()
  } else {
    form.fields['field3'].hide()
  }
}

form.on('field1:change', toggleField3);
form.on('field2:change', toggleField3);

所以基本上,每次我们改变两个家属的价值时,我们都可能会切换字段的可见性。

答案 1 :(得分:0)

所以,事实证明我非常接近,但只是需要做一些不同的事情。

我最终要解决的问题是

  • 迭代key, value对象参数的args {我在这种情况下从arguments[0]得到的参数}
  • 检测value是否为对象
  • 如果是,请将args[key]的值分配给返回对象value的JSON表示的IIFE。

IIFE证明是必要的,因为即使我们改变范围,它也会维持value的价值。

这是我已完成的工作条件类:

var Conditions = function(){

    var args = arguments[0];

    //if we didn't call Conditions() with 'new', this next bit handles that
    if (!(this instanceof Conditions)){
        return new Conditions(args);
    }

    //default value for 'args' if we don't have an arguments object
    if (!_.isObject(args)){
        args = {};
    }

    _.each(args, function(val, key, obj){
        //detect where value is object
        if (_.isObject(val)){
            //replace these values with objectToJSON(value)
            args[key] = (function(obj){ return(JSON.stringify(obj)) })(val);
        }
    });

    return args;
};