我有一个拉力赛扑克应用程序,它是自定义html,其中有一个团队成员的屏幕和一个Scrum Master的屏幕。我需要的是如何在使用这个自定义html应用程序时控制团队成员的并发更新。截至今天,该应用程序仅从最后在并发会话中提交的用户获取最新更新。它会覆盖其他所有数据。如果有人可以发布如何检查并发会话并停止在并发会话中覆盖用户输入的示例代码,那将是很有帮助的。谢谢你的帮助。
Click here for Scrum Master View Screenshot
@kyle - 我试图添加你提到的版本ID
谢谢凯尔。我通过重复获取代码尝试了一种检查versionID的繁琐方法,但是在我的测试中,它证明了versionID没有为并发会话正确设置。我已粘贴了具有versionID检查的代码段。如果需要添加任何内容,请您查看并告诉我。感谢您的帮助
Ext.create('Ext.window.Window', {
title: 'Planning Poker-Team Member view UserStoryNumber : '+userstorynumber, height: 200, width: 400, layout: 'fit',
items: [
//*************** START PANEL FORM 1 *******************
Ext.create('Ext.form.Panel', {
bodyPadding: 5, width: 350, url: 'save-form.php',
layout: { type: 'vbox', align: 'stretch', pack: 'start' },
defaults: { anchor: '100%' },
//Fields
defaultType: 'textfield',
items: [
{ fieldLabel: 'Estimate', name: 'Estimate', allowBlank: false, id: 'estimate' },
{ fieldLabel: 'Justification', name: 'Justification', allowBlank: false, id: 'justification' }
],
// Reset and Submit buttons
buttons: [
//{ text: 'Reset', handler: function () { this.up('form').getForm().reset(); } },
{
text: 'Submit', formBind: true, disabled: true,
handler: function () {
//alert(f_newEstimate('name','points','role','justification'));
var EstimateObject = getExistingEstimates(result);
if (EstimateObject)
console.log('Notes ************ ' + result.get('Notes'));
console.log('Stringfy ************ ' + JSON.stringify(EstimateObject));
//rec.set('PlanEstimate', estFinal);
var jsonobj = f_newEstimate(name, Ext.getCmp('estimate').getValue(), role, Ext.getCmp('justification').getValue());
console.log("json raw is", jsonobj);
//console.log("json justi is", jsonobj.justification);
console.log("PO note is", result.get('c_PONote'));
//var existingPONote = result.get('c_PONote');
//var newponote = existingPONote + ',' + jsonobj;
var CurrentVersionID;
var newVersionID;
//Exp Karthik Starts
var myStore = Ext.create('Rally.data.wsapi.Store', {
model: 'User Story',
autoLoad: true, // <----- Don't forget to set this to true! heh
filters: [
{
property: 'ObjectID',
operator: '=',
value: objectId
}
],
listeners: {
load: function (myStore, myData, success) {
CurrentVersionID = myStore.data.items["0"].data.VersionId;
console.log("Version ID is", myStore.data.items["0"].data.VersionId);
},
scope: this // This tells the wsapi data store to forward pass along the app-level context into ALL listener functions
},
fetch: ['ObjectID', 'c_PONote', 'VersionId'] // Look in the WSAPI docs online to see all fields available!
});
var existingPONote = result.get('c_PONote');
var newponote = '';
if (existingPONote.length == 0) {
newponote = '[' + jsonobj + ']';
}
else {
replacestr = ',' + jsonobj + ']';
newponote = existingPONote.replace(']', replacestr);
}
rec.set('c_PONote', newponote);
var myStore = Ext.create('Rally.data.wsapi.Store', {
model: 'User Story',
autoLoad: true, // <----- Don't forget to set this to true! heh
filters: [
{
property: 'ObjectID',
operator: '=',
value: objectId
}
],
listeners: {
load: function (myStore, myData, success) {
newVersionID = myStore.data.items["0"].data.VersionId;
console.log("Version ID is", myStore.data.items["0"].data.VersionId);
},
scope: this // This tells the wsapi data store to forward pass along the app-level context into ALL listener functions
},
fetch: ['ObjectID', 'c_PONote', 'VersionId'] // Look in the WSAPI docs online to see all fields available!
});
if (CurrentVersionID == newVersionID) {
rec.save();
}
else
{
var myStore = Ext.create('Rally.data.wsapi.Store', {
model: 'User Story',
autoLoad: true, // <----- Don't forget to set this to true! heh
filters: [
{
property: 'ObjectID',
operator: '=',
value: objectId
}
],
listeners: {
load: function (myStore, myData, success) {
newVersionID = myStore.data.items["0"].data.VersionId;
console.log("Version ID is", myStore.data.items["0"].data.VersionId);
},
scope: this // This tells the wsapi data store to forward pass along the app-level context into ALL listener functions
},
fetch: ['ObjectID', 'c_PONote', 'VersionId'] // Look in the WSAPI docs online to see all fields available!
});
var existingPONote = myStore.data.items["0"].data.c_PONote;
var newponote = '';
if (existingPONote.length == 0) {
newponote = '[' + jsonobj + ']';
}
else {
replacestr = ',' + jsonobj + ']';
newponote = existingPONote.replace(']', replacestr);
}
rec.set('c_PONote', newponote);
console.log("Concurrent versions saved", newponote);
rec.save();
}
console.log('Submit Success1');
this.up('window').close();
}
}]
答案 0 :(得分:0)
WSAPI中的所有对象都包含一个VersionId字段,每次更新对象时,该字段在服务器上自动递增。产品处理并发问题的方法是始终获取此VersionId字段。然后用户可以在本地进行更新。当用户保存时,首先再次阅读故事。如果VersionId与首次读取时的版本相同,则可以安全地发送更新。如果VersionId更高,那意味着另一个用户在此期间更新了故事。
如果发生冲突,您可以将本地更改合并到新读取的对象中,然后再次尝试保存。您可以根据需要重复此操作,直到用户能够执行干净保存。