我遇到了问题。
使用ajax我使用:
发送了一个正确形成的JSON对象 $.ajax({
type: "POST",
url: SITE_URL+'/data.php',
dataType: "json",
data: { ajax: 1 },
success: function(data) {
console.log(data);
}
});
然而,Opera和Chrome虽然收到相同的对象,但是按不正确的顺序打印出对象,看起来它们都是按ID号排序而不是单独排序!
有没有办法停止此自动排序?
编辑,在发现它是按索引号排序之后,我认为最好的方法可能是不使用索引来存储object_id,而是存储我想要按顺序排序对象的id号。
但是我仍然想知道是否有办法停止排序。
谢谢
Edit2,我只想指出,我将采用不同的方式来做这件事,因为我觉得我用这种方法滥用对象。但是我仍然想了解为什么Opera和Chrome认为他们有权更改我的对象ID的顺序:
问题在于我试图节省处理能力,假设我们有人有ID,
1.John,2.Frank和3.Sally。然而,这些人中的每一个都具有高度属性集(和其他东西)。 1.约翰.180,2.Frank.220,3.Sally.150。为了节省处理费用,我要求人们根据他们的身高对结果进行排序,这样我就得到了一个包含其他属性的2,1,3的数组。我JSON这个数组并将其发送到浏览器。
现在FF将保留新订单 人们[1]仍然是约翰,但在一个人的循环中,他们将会失灵。
如果我无法解决这个问题,我将不得不在SQL阶段进行排序,并在JS阶段添加额外的循环和排序到数组中,尽管我希望避免对浏览器施加更多压力Js重页。
非常感谢
答案 0 :(得分:23)
有同样的问题,遵循dmc的解决方案,但只是在int值前添加了一个空格,使其成为一个字符串。
使用空格而不是另一个非数字字符的优点是随后的POSTed值可以直接在mySQL搜索子句中使用,而不必再次删除它。
答案 1 :(得分:19)
不同的浏览器以不同的方式处理对象,我的错是尝试使用我构建对象的顺序作为参考,我不应该这样做。
答案 2 :(得分:18)
将整数更改为字符串对我来说不起作用(Chrome,jQuery 1.7.1)。 所以为了保持秩序(是的,它的对象滥用),我改变了这个:
optionValues0 = {"4321": "option 1", "1234": "option 2"};
到这个
optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};
答案 3 :(得分:14)
除非JSON是一个数组,而不是一个对象,否则没有标准表明它必须按某种顺序排列。但是,这不应该是一个问题,因为您不需要遍历对象来获取数据,您可以简单地引用该属性。
答案 4 :(得分:6)
有些浏览器会对int进行排序,另一方面很容易将其更改为字符串并稍后恢复,我的解决方案是将“i”添加到密钥,这就成了一个技巧。适用于每个浏览器:)希望有帮助:)
答案 5 :(得分:5)
我有同样的“问题”,并且不想回去并在代码中做太多改变。弄清楚至少Google Chrome只会重新排序数字索引。只要索引被视为字符串,它就会以“预期”顺序显示。有人可以在Opera上验证这个吗?
答案 6 :(得分:2)
这些解决方案都不适合我(2017年8月)。即使我使用了字符串Chrome和Safari(没有测试其他浏览器)仍然根据字符串进行排序。我所做的是将整数键与值字符串连接起来。 e.g
result[string_value + str(integer_key)] = string_value
这样首先是字符串,浏览器可以自由排序。然后我用一些简单的逻辑将键与值分开。
希望这有帮助。
答案 7 :(得分:1)
似乎最好的方法是完全避免关联数组。当你想发送一个关联数组时,只需将它作为两个独立的数组发送 - 一个键和一个值。这是执行此操作的PHP代码:
$arWrapper = array();
$arWrapper['k'] = array_keys($arChoices);
$arWrapper['v'] = array_values($arChoices);
$json = json_encode($arWrapper);
和简单的JavaScript代码,可以用它做任何你喜欢的事情
for (i=0; i < data['k'].length; i++) {
console.log('key:' + data['k'][i] + ' val:' + data['v'][i]);
}
我遇到了类似的问题并发布在jQuery: $.getJSON sorting the data on Chrome / IE?
上答案 8 :(得分:1)
你需要欺骗谷歌Chrome(和其他人)认为你有一个字符串而不是一个数字。
将JSON更改为{"2423":'abc', "2555":'xyz'}
将无效。
我不得不使用&#34; _2423&#34;和&#34; _2555&#34;作为我的对象中的索引,让它工作。
此外,调试输出到console.log或使用for x in y
给出了与_.each
方法不同的结果(参见下划线框架)。
您可以在JSFiddle中看到我的测试/校对,其中"_"
与无前缀和for x in y
循环:http://jsfiddle.net/3f9jugtg/1/
答案 9 :(得分:1)
我使用以下代码解决了这个问题:
$('.edit_district').editable("/moderator/sale/edit_sale/", {
data : " {'_7':'10 street', '_9':'9 street', '_11':'park'}",
type : 'select',
submit : 'OK',
onblur : 'submit'
});
并在script.php中:
...
case "id_district":
$district = Districts::GetDistrictByID(Database::getInstance(), (int)substr($value,1));
if($district instanceof District){
$data["id_district"] = $district->id_district;
echo $district->title;
}
break;
...
答案 10 :(得分:0)
当我添加另一个区域并需要按特定方式对它进行排序时,我遇到了同样的问题。我在数据库表中添加了一个“排序”字段,然后按我的期望对select进行了排序,原始JSON符合预期,但是我通过AJAX将数据填充到其中的select字段仍按键(region_id)对其进行了排序?我的问题是region_id是一个整数,我通过封装键使其改为字符串来解决它:
while($row = $result->fetch_array()) {
$this->regions["'".$row['region_id']."'"] = $row['region'];
}
旧代码为:
while($row = $result->fetch_array()) {
$this->regions[$row['region_id']] = $row['region'];
}
比在键的另一端添加各种字符要优雅得多。
我希望这可以帮助其他人获得更简洁的代码:-)
答案 11 :(得分:0)
可以提供帮助的一个技巧如下:
在for循环中准备数据时,必须在键中添加“i”,这就成了一个技巧。适用于每个浏览器。
例如:
for(var i=1;i<4;i++){
data[''+i+''+your_random_generatedId+''] = {"questionText":"","answer":"","options":"",noOfOptions:""};
console.log(data[''+i+''+your_random_generatedId+'']); // This prints the log of each object inside data
}
console.log(data); // This will print the Object without sorting
因此,您的对象将如下:
Object {156674: Object, 201705: Object, 329709: Object}
希望这有助于:)
答案 12 :(得分:0)
我对chrome有同样的问题,令人沮丧。我以某种方式发送它,为什么不能让我认真对待它呢?我知道没有“标准”方式,但如果是这样的话,为什么要强加自己的订单?
无论如何,我通过将对象转换为数组来处理它,以便
{ 0: "", 2: "Frame", 1: "Masonry" }
成了
[[ 0, "" ], [ 2, "Frame" ], [ 1, "Masonry" ]]
不得不改变一些javascript,但它最终完美运行。
答案 13 :(得分:0)
我遇到了同样的问题,并花了一些时间来研究甚至导致它的问题,这真是一种痛苦。我最终从索引中删除了ID并使用了array_push,而不是:
$section[$s_id]['Type'] = $booktype;
等。我把它改成了
array_push($sections, array('ID'=>$s_id,
'CourseID'=>$courseid,
'SectionName'=>$secname,
'Order'=>$order,
'Created'=>$created,
'Description'=>$desc
));
这允许我保留PHP的排序,因为新的索引已经按顺序排列(0,1,2,3等,而不是112,56,411等)
答案 14 :(得分:0)
在某些情况下,您需要使用记录ID在后期处理循环中对事物进行分组。在密钥值周围加上引号将起作用。或者您可以在最终数组上使用array_merge来重置密钥。
$processed_array = array(
235=>array("id"=>235,"name"=>"Something"),
27=>array("id"=>27,"name"=>"Something")
);
array_merge($processed_array);
print_r($ processed_array);现在返回以下内容:
$processed_array = array(
0=>array("id"=>235,"name"=>"Something"),
1=>array("id"=>27,"name"=>"Something")
);
答案 15 :(得分:0)
在JSON字符串参数中创建对象标识符,它无需自动排序。
答案 16 :(得分:-1)
当您将数据对象传递给console.log
时,JavaScript将最终调用数据对象的toString()
方法。由于您不喜欢数据的toString()
方法的默认格式,因此您必须自己完成这项工作。
如果你想要那种类型的控件,你可以自己转储对象的字段 - 你必须得到键/字段并对它们进行排序然后自己构建字符串版本。
类似的东西:
for (field in obj)
add field to array
sort array into whatever order you want
for (field in array)
get value of field from obj
create string of field : value, append to main string
console.log(main string)