看来这毕竟是 Sitecore 默认的工作方式(从 7.1 开始),而不是修改和配置的问题。创建新实例后,我可以通过标准值中的演示详细信息向页面添加组件来重新创建问题。问题源于将占位符字段留空。如果是这种情况,则向页面添加组件会显示消息:“发生错误”并且移动组件通常会导致删除。因此,解决此问题的方法是更改所有受影响项目的标准值。当 Sitecore 处理空字段时,似乎会发生一些有趣的事情。这是我用来解决这个问题的方法。
Sitecore 支持人员回复了一个额外的解决方法以避免数据丢失:
将附加的布局定义文件放入 \Website\sitecore\shell\Applications\Page Modes 文件夹并清除浏览器缓存(替换您的 js 文件)。此脚本可防止组件删除并显示以下消息:“组件在视觉上已移动,但如果您在 PE 中移动组件,某些信息可能会丢失。请保存更改(如果禁用保存则重新加载)以查看实际演示和移动组件通过演示详细信息(功能区上的高级选项卡)。” 请注意,此解决方法未经过深入测试,我们建议您在应用任何更改之前备份您的解决方案。
布局定义.js
Sitecore.LayoutDefinition = new function() {
};
Sitecore.LayoutDefinition.insert = function(placeholderKey, id) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
var r = new Object();
r["@id"] = id;
r["@ph"] = placeholderKey;
device.r.splice(0, 0, r);
this.setLayoutDefinition(layoutDefinition);
};
Sitecore.LayoutDefinition.getRendering = function(uid) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
if (!device) {
return null;
}
for (var n = 0; n < device.r.length; n++) {
if (this.getShortID(device.r[n]["@uid"]) == uid) {
return device.r[n];
}
}
};
Sitecore.LayoutDefinition.remove = function(uid) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
this.removeRendering(device, uid);
this.setLayoutDefinition(layoutDefinition);
};
Sitecore.LayoutDefinition.removeRendering = function(device, uid) {
for (n = 0; n < device.r.length; n++) {
if (this.getShortID(device.r[n]["@uid"]) == uid) {
r = device.r[n];
device.r.splice(n, 1);
return r;
}
}
return null;
};
Sitecore.LayoutDefinition.moveToPosition = function(uid, placeholderKey, position) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
var originalPosition = this._getRenderingPositionInPlaceholder(device, placeholderKey, uid);
for (var totalCount = 0; totalCount < device.r.length; totalCount++)
{
var rendering = device.r[totalCount];
if (rendering["@ph"]=="")
{
window.alert('The component is visually moved but some information could be lost if you move the component in PE. Please save the changes (reload page if save is disabled) in order to see actual presentation and move the component via the Presentation Details (Advanced tab on the Ribbon).');
return;
}
}
var r = this.removeRendering(device, uid);
if (r == null) {
return;
}
r["@ph"] = placeholderKey;
if (position == 0) {
device.r.splice(0, 0, r);
this.setLayoutDefinition(layoutDefinition);
return;
}
// Rendering is moving down inside the same placeholder. Decrement the real position, because rendering itself is removed
// from his original position.
if (originalPosition > -1 && originalPosition < position) {
position--;
}
var placeholderWiseCount = 0;
var flag = true;
for (var totalCount = 0; totalCount < device.r.length; totalCount++)
{
var rendering = device.r[totalCount];
if (Sitecore.PageModes.Utility.areEqualPlaceholders(rendering["@ph"], placeholderKey))
{
placeholderWiseCount++;
}
if (placeholderWiseCount == position)
{
device.r.splice(totalCount + 1, 0, r);
break;
}
}
this.setLayoutDefinition(layoutDefinition);
};
Sitecore.LayoutDefinition.getRenderingConditions = function(renderingUid) {
if (!Sitecore.PageModes.Personalization) {
return [];
}
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
var conditions = [];
for (var i = 0; i < device.r.length; i++) {
if (this.getShortID(device.r[i]["@uid"]) == renderingUid && device.r[i].rls) {
var rules = device.r[i].rls.ruleset;
if (rules && rules.rule) {
if(!$sc.isArray(rules.rule)) {
rules.rule = [rules.rule];
}
for (var j = 0; j < rules.rule.length; j++) {
var conditionId = rules.rule[j]["@uid"];
var isActive = Sitecore.PageModes.Personalization.ConditionStateStorage.isConditionActive(renderingUid, conditionId);
conditions.push(new Sitecore.PageModes.Personalization.Condition(
conditionId,
rules.rule[j]["@name"],
isActive
));
}
}
}
}
return conditions;
};
Sitecore.LayoutDefinition.GetConditionById = function(conditionId) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
for (var i = 0; i < device.r.length; i++) {
var rules = device.r[i].rls ? device.r[i].rls.ruleset: null;
if (rules && rules.rule) {
if(!$sc.isArray(rules.rule)) {
rules.rule = [rules.rule];
}
for (var j = 0; j < rules.rule.length; j++) {
if (rules.rule[j]["@uid"] == conditionId) {
return {rule : rules.rule[j]};
}
}
}
}
return {};
};
Sitecore.LayoutDefinition.getRenderingIndex = function(placeholderKey, index) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
var i = 0;
for (n = 0; n < device.r.length; n++) {
if (device.r[n]["@ph"] == placeholderKey) {
if (i == index) {
return n;
}
i++;
}
}
return -1;
};
Sitecore.LayoutDefinition.getRenderingPositionInPlaceholder = function(placeholderKey, uid) {
var layoutDefinition = this.getLayoutDefinition();
var device = this.getDevice(layoutDefinition);
return this._getRenderingPositionInPlaceholder(device, placeholderKey, uid);
};
Sitecore.LayoutDefinition.getLayoutDefinition = function() {
return JSON.parse($sc("#scLayout").val());
};
Sitecore.LayoutDefinition.setLayoutDefinition = function(layoutDefinition) {
var newValue = $sc.type(layoutDefinition) === "string" ? layoutDefinition : JSON.stringify(layoutDefinition);
if ($sc("#scLayout").val() != newValue) {
$sc("#scLayout").val(newValue);
Sitecore.PageModes.PageEditor.setModified(true);
}
};
Sitecore.LayoutDefinition.getDeviceID = function() {
return $sc("#scDeviceID").val();
};
Sitecore.LayoutDefinition.getDevice = function(layoutDefinition) {
var deviceID = this.getDeviceID();
if (!layoutDefinition.r.d) {
return null;
}
//By serialization behaivour. If there is single element- it would not be serialized as array
if (!layoutDefinition.r.d.length) {
layoutDefinition.r.d = [layoutDefinition.r.d];
}
var list = layoutDefinition.r.d;
for (var n = 0; n < list.length; n++) {
var d = list[n];
var id = this.getShortID(d["@id"]);
if (id == deviceID) {
//By serialization behaivour. If there is single element- it would not be serialized as array
if (d.r && !d.r.length) {
d.r = [d.r];
}
return d;
}
}
return null;
};
Sitecore.LayoutDefinition.getShortID = function(id) {
return id.substr(1, 8) + id.substr(10, 4) + id.substr(15, 4) + id.substr(20, 4) + id.substr(25, 12);
};
Sitecore.LayoutDefinition.readLayoutFromRibbon = function() {
var layout = Sitecore.PageModes.PageEditor.ribbon().contentWindow.$("scLayoutDefinition").value;
if (layout && layout.length > 0) {
this.setLayoutDefinition(layout);
return true;
}
return false;
};
Sitecore.LayoutDefinition._getRenderingPositionInPlaceholder = function(device, placeholderKey, uid) {
var counter = 0;
for (var i = 0; i < device.r.length; i++) {
if (Sitecore.PageModes.Utility.areEqualPlaceholders(device.r[i]["@ph"],placeholderKey)) {
if (this.getShortID(device.r[i]["@uid"]) == uid) {
return counter;
}
counter++;
}
}
return -1;
};