work-around attempt 1

This commit is contained in:
Andy Gup 2015-05-01 18:00:16 -06:00
parent 57d286fa9a
commit 1fa55e31ed
2 changed files with 122 additions and 29 deletions

View File

@ -11,12 +11,13 @@ define([
"esri/config",
"esri/layers/GraphicsLayer",
"esri/graphic",
"esri/request",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/urlUtils"],
function (Evented, Deferred, all, declare, array, domAttr, domStyle, query,
esriConfig, GraphicsLayer, Graphic, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, urlUtils) {
esriConfig, GraphicsLayer, Graphic, esriRequest, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, urlUtils) {
"use strict";
return declare("O.esri.Edit.OfflineFeaturesManager", [Evented],
{
@ -101,23 +102,46 @@ define([
var self = this;
// NOTE: At v2.6.1 we've discovered that not all feature layers support objectIdField.
// However, we want to try to be consistent here with how the library is managing Ids.
// However, to try to be consistent here with how the library is managing Ids.
// So, we force the layer.objectIdField to DB_UID. This should be consistent with
// how esri.Graphics assign a unique ID to a graphic. If it is not, then this
// library will break and we'll have to re-architect how we manage UIDs.
layer.objectIdField = this.DB_UID;
var url = null;
if(layer.url) {
url = layer.url;
// we keep track of the FeatureLayer object
this._featureLayers[layer.url] = layer;
}
// Initialize the database as well as set offline data.
if(!this._editStore._isDBInit) {
this._initializeDB(dataStore,callback);
this._initializeDB(dataStore, url, function(success, error) {
if(success && !url) {
// This functionality is specifically for offline restarts
// and attempts to retrieve a feature layer url.
// It's a hack because layer.toJson() doesn't convert layer.url.
this._editStore.getFeatureLayerJSON(function(success,message){
if(success) {
this._featureLayers[message.__featureLayerURL] = layer;
}
else {
console.error("getFeatureLayerJSON() failed.");
}
}.bind(this));
}
// NOTE: If this is an error then _featureLayers[] isn't going to be set correct
callback(success,error);
}.bind(this));
}
else {
callback(true, null);
}
// we keep track of the FeatureLayer object
this._featureLayers[layer.url] = layer;
// replace the applyEdits() method
layer._applyEdits = layer.applyEdits;
@ -1054,7 +1078,7 @@ define([
console.log("offlineFeaturesManager going online");
this._onlineStatus = this.RECONNECTING;
this._replayStoredEdits(function (success, responses) {
var result = {features: {success: success, responses: responses}};
var result = {success: success, responses: responses};
this._onlineStatus = this.ONLINE;
if (this.attachmentsStore != null) {
console.log("sending attachments");
@ -1105,7 +1129,7 @@ define([
*/
getFeatureLayerJSONDataStore: function(callback){
if(!this._editStore._isDBInit){
this._initializeDB(null,function(success) {
this._initializeDB(null, null, function(success) {
if(success){
this._editStore.getFeatureLayerJSON(function(success,message){
callback(success,message);
@ -1123,12 +1147,14 @@ define([
/* internal methods */
/**
* Intialize the database and push featureLayer JSON to DB if required
* Intialize the database and push featureLayer JSON to DB if required.
* NOTE: also stores feature layer url in hidden dataStore property dataStore.__featureLayerURL.
* @param dataStore Object
* @param url Feature Layer's url. This is used by this library for internal feature identification.
* @param callback
* @private
*/
_initializeDB: function(dataStore,callback){
_initializeDB: function(dataStore,url,callback){
var editStore = this._editStore;
@ -1153,6 +1179,14 @@ define([
////////////////////////////////////////////////////
if (typeof dataStore === "object" && result === true && (dataStore !== undefined) && (dataStore !== null)) {
// Add a hidden property to hold the feature layer's url
// When converting a feature layer to json (layer.toJson()) we lose this information.
// This library needs to know the feature layer url.
if(url) {
dataStore.__featureLayerURL = url;
}
editStore.pushFeatureLayerJSON(dataStore, function (success, err) {
if (success) {
callback(true, null);
@ -1479,7 +1513,7 @@ define([
console.log("NOTICE: you may need to run OfflineFeaturesManager.initAttachments(). Check the Attachments doc for more info. Layer id: " + layer.id + " accepts attachments");
}
else if(layer.hasAttachments === false){
console.error("WARNING: Layer " + layer.id + "doesn't seem to accept attachments. Recheck the layer permissions.");
console.error("WARNING: Layer " + layer.id + " doesn't seem to accept attachments. Recheck the layer permissions.");
callback(false,"WARNING: Attachments not supported in layer: " + layer.id);
}
@ -1718,6 +1752,12 @@ define([
_internalApplyEdits: function (layer, id, tempObjectIds, adds, updates, deletes) {
var dfd = new Deferred();
this._makeEditRequest(layer.url,adds,updates,deletes).then(function(result){
console.log(result);
},function(error){
console.log("error");
});
layer._applyEdits(adds, updates, deletes,
function (addResults, updateResults, deleteResults) {
layer._phantomLayer.clear();
@ -1760,6 +1800,47 @@ define([
return dfd.promise;
},
_makeEditRequest: function(url,adds, updates, deletes) {
var dfd = new Deferred();
var data = new FormData();
data.append("f", "json");
if(adds.length > 0) {
data.append("adds", JSON.stringify(adds));
}
if(updates.length > 0) {
data.append("updates", JSON.stringify(updates));
}
if(deletes.length > 0) {
data.append("deletes", JSON.stringify(deletes));
}
var req = new XMLHttpRequest();
req.open("POST", url + "/applyEdits", true);
req.onload = function()
{
if( req.status === 200 && req.responseText !== "")
{
var obj = JSON.parse(this.response);
dfd.resolve(obj);
//callback(obj.addResults, obj.updateResults, obj.deleteResults);
//callback(this.response);
//Object.keys(this.response).forEach(function(key) {
// console.log(key, this.response[key]);
//});
}
};
req.onerror = function(e)
{
console.log("_getTileInfoPrivate failed: " + e);
dfd.error(e);
};
req.send(data);
return dfd.promise;
},
/**
* Deprecated @ v2.5. Internal-use only
* @returns {string}

View File

@ -221,7 +221,7 @@
* This is a utility check to 100% validate if the application is online or
* offline prior to launching any map functionality.
*/
verifyOnline(function(result) {
validateOnline(function(result) {
if(result) {
_isOnline = true;
setUIOnline();
@ -271,9 +271,6 @@
*/
function startMap() {
//Make sure map shows up after a browser refresh
Offline.check();
tileLayer = new O.esri.Tiles.OfflineTileEnablerLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",function(evt){
console.log("Tile Layer initialized for offline. App state is: " + Offline.state);
},_isOnline);
@ -408,10 +405,13 @@
if(success){
// Use the feature layer returns from getFeatureDefinition() to reconstitute the layer
busStopFeatureLayer = new FeatureLayer(JSON.parse(dataStore.featureLayerCollection), {
mode: FeatureLayer.MODE_SNAPSHOT,
outFields: ["GlobalID","BSID","ROUTES","STOPNAME"]
});
// We don't have to set any other properties on the layer because we are using it
// in SNAPSHOT mode which downloads all features within the given extent.
busStopFeatureLayer = new FeatureLayer(JSON.parse(dataStore.featureLayerCollection));
if(busStopFeatureLayer.url == null){
busStopFeatureLayer.url = dataStore.featureLayerUrl;
}
// Set the graphic symbols to red diamond to make it easy to click on them
// on a mobile device.
@ -460,9 +460,9 @@
// Refer to "Using the Proxy Page" for more information: https://developers.arcgis.com/en/javascript/jshelp/ags_proxy.html
offlineFeaturesManager.proxyPath = null;
offlineFeaturesManager.on(offlineFeaturesManager.events.EDITS_ENQUEUED, editsEnqueued);
offlineFeaturesManager.on(offlineFeaturesManager.events.EDITS_ENQUEUED, updateStatus);
offlineFeaturesManager.on(offlineFeaturesManager.events.EDITS_SENT, updateStatus);
offlineFeaturesManager.on(offlineFeaturesManager.events.ALL_EDITS_SENT, allEditsSent);
offlineFeaturesManager.on(offlineFeaturesManager.events.ALL_EDITS_SENT, updateStatus);
offlineFeaturesManager.on(offlineFeaturesManager.events.EDITS_SENT_ERROR, editsError);
}
@ -495,7 +495,14 @@
// This will force the library to check for pending edits and attempt to
// resend them to the Feature Service.
if(_isOnline){
offlineFeaturesManager.goOnline();
offlineFeaturesManager.goOnline(function(result){
if(!result.success){
alert("There was a problem when attempting to go back online.");
}
});
}
else {
offlineFeaturesManager.goOffline();
}
callback(true);
@ -504,7 +511,7 @@
callback(false);
alert("Unable to initialize the database. " + error);
}
},/* This is the optional offline configuration property */featureLayerJSON);
}.bind(this),/* This is the optional offline configuration property */featureLayerJSON);
}
/**
@ -571,10 +578,12 @@
}
function getFeatureLayerJSON() {
return {
"featureLayerCollection": JSON.stringify(busStopFeatureLayer.toJson()),
"zoomLevel": map.getZoom(),
"centerPt" : (map.extent.getCenter()).toJson()
"centerPt" : (map.extent.getCenter()).toJson(),
"featureLayerUrl": busStopFeatureLayer.url
}
}
@ -752,15 +761,17 @@
* Use this in conjunction with the offline checker library: offline.min.js
* @param callback
*/
function verifyOnline(callback) {
function validateOnline(callback) {
var req = new XMLHttpRequest();
req.open("GET", "http://esri.github.io/offline-editor-js/samples/images/blue-pin.png?" + (Math.floor(Math.random() * 1000000000)), true);
req.onload = function() {
if( req.status === 200 && req.responseText !== "") {
req = null;
callback(true);
}
else {
console.log("verifyOffline failed");
req = null;
callback(false);
}
};
@ -795,10 +806,11 @@
alert("There was a problem. Not all edits were synced with the server. " + JSON.stringify(evt));
}
function updateStatus() {
busStopFeatureLayer.pendingEditsCount(function(count) {
pendingEdits.innerHTML = count;
});
function updateStatus(evt) {
console.log("TEST");
// busStopFeatureLayer.pendingEditsCount(function(count) {
// pendingEdits.innerHTML = count;
// });
}
});
</script>