2

我正在使用 BackboneJS,我有一个从启用 oData 的 WebAPI 获取数据的集合。在获取数据时,我使用 oData $filter 传入了一些额外的参数。

它看起来有点像这样:

collection.fetch({
   data: $.param({ '$filter': 'Filter1 eq ' + filter.get('filter1') + 
                   ' and Filter2 eq ' + filter.get('filter2') }),
   //some more stuff...
})

我基本上是在运行一个向导并在此过程中建立这个过滤器模型。来自此过滤器模型的每个值要么是字符串值,要么是空字符串。我已经覆盖了过滤器模型上的 get 方法,以确保从中获得正确的值。请注意,如果字符串值不为空,则在字符串值周围添加单引号,如果为空,则返回包含单词“null”的字符串值。

var Filter = Backbone.Model.extend({        
    get: function (attributes, options) {
        var value = Backbone.Model.prototype.get.call(this, attributes, options);
        if (value == '') return 'null';
        else return "'" + value + "'";
    }
});

假设我的模型如下所示:

{filter1: 'filter1', filter2: 'filter2'}

现在,如果我在 Chrome 和 Firefox 中获取集合,生成的请求将如下所示:

replacedapiurl?%24filter=Filter1+eq+%27filter1%27+and+Filter2+eq+%27filter2%27

这非常好,它在 Firefox 和 Chrome 中都很好用。我遇到的问题是在 IE10 中这不起作用。由于某种原因,生成的请求如下所示:

replacedapiurl?%24filter=Filter1+eq+'+filter1+'+and+Filter1+eq+'+filter1+'

当我将它设置为 IE9 模式时,它也是如此。当我将它设置为 IE8 模式时,它突然开始工作。

现在我尝试使用 EncodeURI()、EncodeURIComponent()、escape() 并在单引号前添加 '\',无论是在我重写的 get 方法中还是在 $.param 位中。但没有任何效果。添加 '\' 没有任何作用,所有编码都是对添加的 '+' 符号进行编码,如下所示:

replacedapiurl?%24filter=Filter1+eq+'%2520filter1%2520'+and+Filter1+eq+'%2520filter1%2520'

这也不是我所追求的。

有谁知道为什么会这样?为什么具有这种行为的 IE 浏览器版本之间存在差异?我该如何解决?我需要将单引号转换为“%27”,最好无需编写任何浏览器特定代码。

编辑:我刚刚有人在 IE9 上进行检查,效果很好,所以只有在使用 IE10 时——以及在 IE9 模式下使用 IE10 时——它才不起作用。

4

1 回答 1

1

好的,我认为这超出了我的范围,但最后它不是,我自己修复了它。以防万一将来它可能对任何人有所帮助,我将解释为什么会发生这种情况。

过滤器对象中的值来自“选择”,“选择”在主干视图内,并且选择填充有许多“选项”视图。出于某种原因,我为我的选项视图设置了一个模板,如下所示:

<script type="text/template" id="option-template">
<%=value%>
</script>

上面 HTML 中的换行符使得“选项”在“选择”内呈现,并在值的两侧添加了额外的空间。现在我尝试过的所有其他浏览器和 IE10 之间的区别似乎在于,在 IE10 中,我的选项视图中的那些空格不会被 jQuery 的 val() 修剪,而在所有其他浏览器中,它们在读取值时会被修剪带有 val() 的“选择”。这导致额外的空格在值的两侧变成了一个“+”号,就像 URL 中的所有其他空格一样,就是问题所在!单引号本身不需要转换为 %27,它应该可以工作,这是我从这个问题的答案中得到的

如果我像这样在一行中编写模板,我就不会遇到问题:

<script type="text/template" id="option-template"><%=value%></script>

无论如何,我只是一起摆脱了模板并将我的选项视图更改为:

var optionView = Backbone.View.extend({
    tagName: "option",
    render: function () {
        this.$el.html(this.model.get('value'));
    }
});

这解决了所有问题,选项周围不再有多余的空格。

我想吸取的教训是,当您使用 jQuery 读取选择框值时,IE10 不会删除值周围的空格,如下所示:

var value = $('#id').val();

在任何其他浏览器中,如果选项周围有空格,如“value”,它们将自动被修剪,value 将为“value”,在 IE10 中,情况并非如此,value 将为“value”。

于 2012-12-17T07:22:51.867 回答