这是我为此写的代码...... 功能深层复制 rally.PortfolioItemDeepCopy = function(rallyDataSource,config){ var portfolioitemBuffer = []; var firstPortfolioItem = null; var firstStory = null; var finishedCallback; var that = this; //dojo.connect(obj,event,context,method,dontFix); this._fireEvent = function(eventName,eventArgs){
if (config && config.eventListeners[eventName] && dojo.isFunction(config.eventListeners[eventName])) {
config.eventListeners[eventName](that, eventArgs);
}
};
// removes private and read only fields to keep from pushing them up.
this.filterObject = function (object) {
return object;
};
this._addObject = function(object, typeName, callback) {
var item = dojo.clone(object);
item = this.filterObject(item);
function errorFunctionWrapper(error) {
if (dojo.isArray(error.Errors)) {
var errorMessage = error.Errors.pop();
if (errorMessage.indexOf("Not authorized to create:") >= 0) {
errorMessage = "Unable to create an object. This can happen due to a child or task being in a project you do not have write permissions to.";
}
rally.sdk.ui.AppHeader.showMessage("error", errorMessage, 10000);
}
else if(dojo.isObject(error)&&error.message){
rally.sdk.ui.AppHeader.showMessage("error", error.message, 10000);
error = [error.message];
}
if (dojo.isFunction(config.onError)) {
config.onError(error);
}
}
rallyDataSource.create(typeName, item, callback, errorFunctionWrapper);
};
this._copyAllFromBuffer = function() {
if (portfolioitemBuffer.length > 0) {
var portfolioitem = portfolioitemBuffer.pop();
that._copyPortfolioItem(portfolioitem.ref, portfolioitem.parent, that._copyAllFromBuffer);
}
else {
if (finishedCallback) {
finishedCallback(firstPortfolioItem);
}
}
};
this._addPortfolioItemsToBuffer = function(portfolioitemArray, parentRef) {
dojo.forEach(portfolioitemArray, function (portfolioitem) {
portfolioitemBuffer.push({
ref: portfolioitem._ref,
parent: parentRef
});
});
};
this._copyPortfolioItem = function(ref, parentRef, callback) {
rallyDataSource.getRallyObject(ref, function (foundObject) {
var type = "feature"
that._fireEvent("portfolioitemPreAdd", {portfolioitem:foundObject});
if (parentRef) {
foundObject.Parent = parentRef;
}
else {
foundObject.Name = "(Copy of) " + foundObject.Name;
}
that._addObject(foundObject, type, function (portfolioitemRef) {
if (!firstPortfolioItem) {
firstPortfolioItem = portfolioitemRef;
}
that._fireEvent("portfolioitemPostAdd", {});
that._addPortfolioItemsToBuffer(foundObject.Children, portfolioitemRef);
that._copyStoriesToPortfolioItem(foundObject.Stories, portfolioitemRef, callback);
that._copyTasksToStory(foundObject.Tasks, portfolioitemRef, callback);
}, null);
});
};
this._copyTasksToStory = function(tasks, storyRef, callback) {
//Copy the array
var localTasks = tasks.slice(0);
if (localTasks.length > 0) {
var task = localTasks.pop();
that._copyTask(task._ref, storyRef, function () {
that._copyTasksToStory(localTasks, storyRef, callback);
});
}
else {
callback();
}
};
this._copyStoriesToPortfolioItem = function(stories, portfolioitemRef, callback) {
//Copy the array
var localStories = stories.slice(0);
if (localStories.length > 0) {
var task = localStories.pop();
that._copyStory(story._ref, portfolioitemRef, function () {
that._copyStoriesToPortfolioItem(localStories, portfolioitemRef, callback);
});
}
else {
callback();
}
};
this._copyStory = function(ref, portfolioitemRef, callback) {
rallyDataSource.getRallyObject(ref, function (foundObject) {
var type = "hierarchicalrequirement";
foundObject.WorkProduct = portfolioitemRef;
that._fireEvent("storyPreAdd", {story:foundObject});
that._addObject(foundObject, type, function (ref, warnings) {
if (callback) {
that._fireEvent("storyPostAdd", [ref]);
callback();
}
}, null);
});
};
this._copyTask = function(ref, storyRef, callback) {
alert('helooooddddddddddddd task', ref);
rallyDataSource.getRallyObject(ref, function (foundObject) {
var type = "task";
foundObject.WorkProduct = storyRef;
that._fireEvent("taskPreAdd", {task:foundObject});
that._addObject(foundObject, type, function (ref, warnings) {
if (callback) {
that._fireEvent("taskPostAdd", [ref]);
callback();
}
}, null);
});
};
this.copyPortfolioItem = function (ref, callback) {
alert('hello');
that._copyPortfolioItem(ref, undefined, that._copyAllFromBuffer);
finishedCallback = callback;
};
};
</script>
<style type="text/css">
/* Add app styles here */
</style>
<script type="text/javascript">
rally.addOnLoad(function() {
var selectedValue = null;
var tasksAdded = 0;
var storiesAdded = 0;
var portfolioitemAdded = 0;
var searchPortfolioItem;
var searchStories;
var goButton, chooseButton;
var chooser;
var waiter;
var dataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
function taskPostAdd(object, args) {
tasksAdded = tasksAdded + 1;
displayTasksAdded(tasksAdded);
}
function taskPreAdd(object, args) {
dojo.byId("currentInfo").innerHTML = "Adding Task " + args.task.FormattedID + " - " + args.task.Name;
}
function storyPreAdd(object, args) {
dojo.byId("currentInfo").innerHTML = "Adding User Story " + args.story.FormattedID + " - " + args.story.Name;
}
function storyPostAdd(object, args) {
storiesAdded = storiesAdded + 1;
displayStoriesAdded(storiesAdded);
}
function displayStoriesAdded(count) {
dojo.byId("storyResult").innerHTML = "Stories added: " + count;
}
function portfolioitemPreAdd(object, args) {
dojo.byId("currentInfo").innerHTML = "Adding PortfolioItem " + args.story.FormattedID + " - " ;
}
function portfolioitemPostAdd(object, args) {
portfolioitemsAdded = portfolioitemsAdded + 1;
displayPortfolioItemsAdded(portfolioitemsAdded);
}
function displayPortfolioItemsAdded(count) {
dojo.byId("portfolioitemResult").innerHTML = "PortfolioItems added: " + count;
}
function displayTasksAdded(count) {
dojo.byId("taskResult").innerHTML = "Tasks added: " + tasksAdded;
}
function portfolioitemCopied(portfolioitem) {
dojo.byId("currentInfo").innerHTML = "Copy complete: ";
var link = new rally.sdk.ui.basic.Link({
item: portfolioitem,
text: portfolioitem._refObjectName
});
link.display('currentInfo');
goButton.setEnabled(true);
chooseButton.setEnabled(true);
if(waiter) {
waiter.hide();
waiter = null;
}
}
function buttonPressed() {
if (selectedValue) {
var config = {
eventListeners:{
portfolioitemPreAdd:portfolioitemPreAdd,
portfolioitemPostAdd:portfolioitemPostAdd,
storyPreAdd:storyPreAdd,
storyPostAdd:storyPostAdd,
taskPreAdd:taskPreAdd,
taskPostAdd:taskPostAdd
}
};
portfolioitemsAdded = 0;
displayPortfolioItemsAdded(portfolioitemsAdded);
tasksAdded = 0;
displayTasksAdded(tasksAdded);
storiesAdded = 0;
displayStoriesAdded(storiesAdded);
dojo.byId("currentInfo").innerHTML = "";
var copy = new rally.PortfolioItemDeepCopy(dataSource, config);
goButton.setEnabled(false);
chooseButton.setEnabled(false);
waiter = new rally.sdk.ui.basic.Wait({});
waiter.display('wait');
copy.copyPortfolioItem(rally.sdk.util.Ref.getRelativeRef(selectedValue), portfolioitemCopied);
}
}
function onChooserClose(chooser, args) {
if (args.selectedItem) {
selectedValue = args.selectedItem;
goButton.setEnabled(true);
dojo.byId('portfolioitemBox').innerHTML = args.selectedItem.FormattedID + ' - ' + args.selectedItem.Name;
}
}
function showChooser() {
var chooserConfig = {
fetch:"FormattedID,Name,Description",
type: "PortfolioItem",
title: "Feature Chooser"
};
chooser = new rally.sdk.ui.Chooser(chooserConfig, dataSource);
chooser.addEventListener('onClose', onChooserClose);
chooser.display();
}
rally.addOnLoad(function () {
goButton = new rally.sdk.ui.basic.Button({
text: "Copy",
enabled: false
});
goButton.addEventListener('onClick', buttonPressed);
goButton.display('goButton');
chooseButton = new rally.sdk.ui.basic.Button({
text: "Choose"
});
chooseButton.addEventListener('onClick', showChooser);
chooseButton.display('chooseButton');
showChooser();
rally.sdk.ui.AppHeader.setHelpTopic("252");
});
});
</script>
</head>
<body>
<div id="container">
<div style="float:left">
<span id="chooseButton"></span>
<span id="portfolioitemBox" style="line-height:18px;vertical-align:middle">[No feature selected]</span>
<span id="goButton"></span>
</div>
<div id="wait" style="float:left; height: 16px; width: 24px;"></div>
<div style="margin-left:5px;padding-top:10px;clear:both">
<div id="currentInfo" style="height:16px"></div>
<div id="portfolioitemResult" style="margin-top:10px"></div>
<div id="storyResult"></div>
<div id="taskResult"></div>
</div>
</div>
</body>
</html>