How to do a synchronous call with jaydata - javascript

I'm a bit confused about the asynchous call to the DataBase.
I just want to have a javasctipt adapter class for the calls to the web sql. But I'm not quite sure how to do this. Propably somebody have a good hint for me.
The function OfflneAppDBAdapter.prototype.IsDeviceConfigured() should return true or false depending if there are any items in the Table DeviceConfig.
function OfflneAppDBAdapter() {
self = this;
this.deviceIsConfigured = false;
this.Init = function () {
$data.Entity.extend("$de.offlineapp.DeviceConfig", {
Id: { type: "int", key: true, computed: true },
Name: { type: "string", required: true },
Token: { type: "string" },
Type: { type: "string" }
});
$data.EntityContext.extend("$de.offlineapp.DataContext", {
DeviceConfig: { type: $data.EntitySet, elementType: $de.offlineapp.DeviceConfig }
});
}
self.Init();
$de.offlineapp.context = new $de.offlineapp.DataContext({
name: "webSql", databaseName: "OfflineApp"
});
$de.offlineapp.context.onReady(function () {
});
}
// ************************************************************************
// PUBLIC METHODS -- ANYONE MAY READ/WRITE
// ************************************************************************
OfflneAppDBAdapter.prototype.AddDeviceConfig = function (deviceName, deviceToken, deviceTyp) {
$de.offlineapp.context.onReady(function () {
var promise = $de.offlineapp.context.DeviceConfig.toArray(function (x) {
if (x.length == 0) {
var emp = new $de.offlineapp.DeviceConfig({ Name: deviceName, Token: deviceToken, Type: deviceTyp });
$de.offlineapp.context.DeviceConfig.add(emp);
$de.offlineapp.context.saveChanges();
}
}
)
});
}
OfflneAppDBAdapter.prototype.IsDeviceConfigured = function () {
$de.offlineapp.context.onReady(function () {
var promise = $de.offlineapp.context.DeviceConfig.toArray(function (x) {
if (x.length == 0) {
this.deviceIsConfigured = true;
}
}
)
});
return this.deviceIsConfigured;
}
var myOfflineAppDBAdapter = new OfflneAppDBAdapter();
myOfflineAppDBAdapter.AddDeviceConfig("DeviceName", "Token", "iPad");
console.log(myOfflineAppDBAdapter.IsDeviceConfigured());
As expected the console prints "false". I' aware that the jaydata call works with callbacks and the callbacks are not part of the main class. But there must be a possibility to do so?
I would really apprechiate any help.
Thank you in advance....
Chris
UPDATE:
As you requested the startup code:
function OfflineApplication()
{
self = this;
}
OfflineApplication.prototype.StartApplication = function () {
//Check if online, then sync and
if (navigator && navigator.onLine === true) {
this.IsDeviceConfigured();
}
else {
}
}
///check if the device has a base configuration
OfflineApplication.prototype.IsDeviceConfigured = function () {
myOfflineAppDBAdapter.GetDeviceConfiguration(function (result) {
if (result.length > 0) {
myOfflineAppDBAdapter.deviceIsConfigured = true;
myOfflineApplication.HasDeviceAnApplication();
}
else {
///Get the device base conf from the server.
myOfflineAppSynchronisationAdapter.getDeviceConfigurationByToken(token, myOfflineApplication.HasDeviceAnApplication);
myOfflineAppDBAdapter.deviceIsConfigured = true;
}
});
}
///check if the device has an "application config" in general
OfflineApplication.prototype.HasDeviceAnApplication = function () {
myOfflineAppDBAdapter.GetDeviceAnApplication(function (result) {
if (result.length > 0) {
myOfflineApplication.IsDeviceApplicationVersionLatest(result);
}
else {
myOfflineApplication.GetApplication(false);
}
});
}
///the application config could differ from time to time, so we have to check if a different application should be synct with the device
OfflineApplication.prototype.IsDeviceApplicationVersionLatest = function (result) {
myOfflineAppDBAdapter.DeleteDeviceAnApplication(function () { });
console.log(result);
}
///get the application from the server
OfflineApplication.prototype.GetApplication = function (clearConfig) {
if (clearConfig === true)
{
}
myOfflineAppSynchronisationAdapter.getDeviceApplicationByToken(token, myOfflineApplication.LoadApplication);
}
OfflineApplication.prototype.LoadApplication = function () {
console.log('Now everything is finde and the application gets loaded..');
}
var myOfflineAppDBAdapter = new OfflneAppDBAdapter();
var myOfflineAppSynchronisationAdapter = new OfflineAppSynchronisationAdapter();
var myOfflineApplication = new OfflineApplication();
myOfflineApplication.StartApplication();

There is no sync way. You handling promises wrong. Make your code simple :) You'll need something like this:
$data.Entity.extend("$de.offlineapp.DeviceConfig", {
Id: { type: "int", key: true, computed: true },
Name: { type: "string", required: true },
Token: { type: "string" },
Type: { type: "string" }
});
$data.EntityContext.extend("$de.offlineapp.DataContext", {
DeviceConfig: { type: $data.EntitySet, elementType: $de.offlineapp.DeviceConfig }
});
var context = new $de.offlineapp.DataContext({
name: "webSql", databaseName: "OfflineApp"
});
function AddDeviceConfig(deviceName, deviceToken, deviceTyp) {
return context.DeviceConfig.toArray()
.then(function (x) {
if (x.length == 0) {
var emp = new $de.offlineapp.DeviceConfig({ Name: deviceName, Token: deviceToken, Type: deviceTyp });
context.DeviceConfig.add(emp);
return context.saveChanges();
}
})
}
function IsDeviceConfigured() {
return context.DeviceConfig.toArray()
.then(function (x) {
return x.length > 0;
})
}
context.onReady()
.then(IsDeviceConfigured)
.then(console.log)
.then(function() { return AddDeviceConfig("DeviceName", "Token", "iPad"); })
.then(IsDeviceConfigured)
.then(console.log);
here's a fiddle which does this: http://jsfiddle.net/JayData/cpT5q/1/

Related

Could I use method call from mounted function?

Could I use method call from mounted function?
in my code, I used this method.
mounted() {
this.initEvent();
this.getnewD(
$(function () {
$("#file-manager").dxFileManager({
name: "fileManager",
fileSystemProvider: customProvider,
currentPath: "Documents",
rootFolderName: "Root",
height: 450,
onErrorOcurred: function (e) {
debugger;
console.log(e);
},
permissions: {
create: true,
copy: true,
move: true,
delete: true,
rename: true,
},
customizeDetailColumns: (columns) => {
columns.push({
caption: "Creator",
dataField: "dataItem.creator",
});
return columns;
},
});
}));
},
And in my methods, I tried to used this methods to call mounted function.
But I got the customProvider is not a function.
So where has problem in my code?
methods: {
arr.forEach((item) => {
let tokens = item.path.replace(/^\/|\/$/g, "").split("/");
let current = tree;
for (let i = 0; i < tokens.length; i++) {
if (!current[tokens[i]]) {
current[tokens[i]] = {};
}
current = current[tokens[i]];
}
});
const parseNode = function (node) {
return Object.keys(node).map((key) => {
if (Object.keys(node[key]).length === 0) {
return {
isDirectory: false,
name: key,
};
}
return {
isDirectory: true,
name: key,
items: parseNode(node[key]),
};
});
};
let result = parseNode(tree);
var objectProvider =
new DevExpress.fileManagement.ObjectFileSystemProvider({
data: new_r,
});
var customProvider =
new DevExpress.fileManagement.CustomFileSystemProvider({
getItems: function (pathInfo) {
return objectProvider.getItems(pathInfo);
},
renameItem: function (item, name) {
if (item.name == "Parent1") {
console.log("error in custom provider");
throw {
errorId: 0,
fileItem: item,
};
console.log("error in custom provider");
} else return objectProvider.renameItem(item, name);
},
createDirectory: function (parentDir, name) {
if (parentDir.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else return objectProvider.createDirectory(parentDir, name);
},
deleteItem: function (item) {
console.log(item);
if (item.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else return objectProvider.deleteItems([item]);
},
moveItem: function (item, destinationDir) {
if (item.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else
return objectProvider.moveItems([item], destinationDir);
},
copyItem: function (item, destinationDir) {
if (item.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else
return objectProvider.copyItems([item], destinationDir);
},
});
let new_r = (self.fileSystemProvider = [
{
name: "Security Manager",
isDirectory: true,
items: result,
},
]);
}
I could got the data, but couldn't got some function and displayed the customProvider is not a function.
This has no proper function name in methods: { }
arr.forEach((item) => { ... }
Your methods need to be named!
You need something like that in your methods: object:
methods: {
myfunction(items) {
items.forEach((item) => {
...
}
}
Now you can call myfunction(arr) somewhere else in your script tags
mounted() works with plain js code inside because it is a named lifecycle hook. The methods: { } object however is not a function.

Unable to get property of undefined or null reference UWP

I have the following code in my visual studio and it works perfectly well au a UWP app on my desktop win10, albeit it does not work on my windows phone as a UWP app. I also tried running my simple webapp as from a webserver and loading it in the Edge and it works perfectly.
What should be the problem?
My code looks like this. I omitted some parts:
var model = {
db: {},
goalsobj: {},
goals: [],
init: function() {
var openReq = window.indexedDB.open("GoalsDB");
openReq.onupgradeneeded = function (event) {
model.db = event.target.result;
var objectStore = model.db.createObjectStore("Goals", { keyPath: "id" });
objectStore.createIndex("id","id", {unique:true});
};
openReq.onsuccess = function (event) {
model.db = event.target.result
model.db.transaction("Goals", "readonly").objectStore("Goals").count().onsuccess = function (event) {
if (event.target.result == 0) {
console.log("indexeddb empty");
var goalstemplate = {
id: "idee",
goals: [{ "name": "Task1" }, { "name": "Task2" }, { "name": "Task3" }]
}
var addReq = model.db.transaction("Goals", "readwrite").objectStore("Goals").add(goalstemplate);
} else {
model.db.transaction("Goals", "readonly").objectStore("Goals").get("idee").onsuccess = function (e) {
model.goalsobj = e.target.result;
//console.log(e.target.result);
model.goals = model.goalsobj.goals;
goalfunc.makeList(); //model should not talk to view, but this case it is amust, because if I remove this, it does not render at boot.
}
}
}
openReq.onerror = function (event) {
console.log("Operation failed");
}
}
},
add: function(goalname) {
model.goals.push(
{
"name": goalname
});
model.savedb();
},
move: function (id,updown) {
if (updown == "up") {
model.goals.splice((id-1), 0, model.goals.splice(id, 1)[0]);
};
if (updown == "down") {
model.goals.splice((id+1), 0, model.goals.splice(id, 1)[0]);
};
},
savedb: function(){
//console.log(goals);
var update = model.db.transaction("Goals", "readwrite").objectStore("Goals").put(model.goalsobj);
update.onerror = function (event) {
console.log(event);
};
},
};
Now When I rund this cond on my device it sais:
Unhandled exception at line 28, column 25 in ms-appx-web://1318f74a-397e-4958-aa6b-c8d11b7c5dce/js/main.js
0x800a138f - JavaScript runtime error: Unable to get property 'goals' of undefined or null reference
I have tested your code in my device (Device: Microsoft RM-1118 OSVersion:WindowsMobile 14393). It is working fine. As you can see I placed a button on the html page. The action of button click will execute model.init(), and then I set a break-point at model.goals = model.goalsobj.goals;. When click button the second time and model.goals will be set right value.
So I think the issue may happen in your target device or your GoalsDB was destroyed. Because the cause of Unable to get property 'goals' of undefined or null reference is that model.goalsobj was not set right value. Please check whether those operations have changed your database structure, such as moving operation. You can show more detail about your target device, and I will help you.
(function () {
document.getElementById("createDatabase").addEventListener("click", createDB, false);
function createDB() {
model.init();
}
})();
var model = {
db: {},
goalsobj: {},
goals: [],
init: function () {
var openReq = window.indexedDB.open("GoalsDB");
openReq.onupgradeneeded = function (event) {
model.db = event.target.result;
var objectStore = model.db.createObjectStore("Goals", { keyPath: "id" });
objectStore.createIndex("id", "id", { unique: true });
};
openReq.onsuccess = function (event) {
model.db = event.target.result
model.db.transaction("Goals", "readonly").objectStore("Goals").count().onsuccess = function (event) {
if (event.target.result == 0) {
console.log("indexeddb empty");
var goalstemplate = {
id: "idee",
goals: [{ "name": "Task1" }, { "name": "Task2" }, { "name": "Task3" }]
}
model.db.transaction("Goals", "readwrite").objectStore("Goals").add(goalstemplate);
} else {
model.db.transaction("Goals", "readonly").objectStore("Goals").get("idee").onsuccess = function (e) {
model.goalsobj = e.target.result;
//console.log(e.target.result);
if (model.goalsobj.goals != undefined) {
model.goals = model.goalsobj.goals;
} else {
console.log(e.target.result);
}
//goalfunc.makeList(); //model should not talk to view, but this case it is amust, because if I remove this, it does not render at
}
}
}
openReq.onerror = function (event) {
console.log("Operation failed");
}
}
},
add: function (goalname) {
model.goals.push(
{
"name": goalname
});
model.savedb();
},
move: function (id, updown) {
if (updown == "up") {
model.goals.splice((id - 1), 0, model.goals.splice(id, 1)[0]);
};
if (updown == "down") {
model.goals.splice((id + 1), 0, model.goals.splice(id, 1)[0]);
};
},
savedb: function () {
//console.log(goals);
var update = model.db.transaction("Goals", "readwrite").objectStore("Goals").put(model.goalsobj);
update.onerror = function (event) {
console.log(event);
};
}
};

javascript: Alter the output of a function to the specified decimal place

I am not very good with my javascript but recently needed to work with a library to output an aggregated table. Was using fin-hypergrid.
There was a part where I need to insert a sum function (rollups.sum(11) in this example)to an object so that it can compute an aggregated value in a table like so:
aggregates = {Value: rollups.sum(11)}
I would like to change this value to return 2 decimal places and tried:
rollups.sum(11).toFixed(2)
However, it gives the error : "rollups.sum(...).toFixed is not a function"
If I try something like:
parseFloat(rollups.sum(11)).toFixed(2)
it throws the error: "can't assign to properties of (new String("NaN")): not an object"
so it has to be a function object.
May I know if there is a way to alter the function rollups.sum(11) to return a function object with 2 decimal places?
(side info: rollups.sum(11) comes from a module which gives:
sum: function(columnIndex) {
return sum.bind(this, columnIndex);
}
)
Sorry I could not post sample output here due to data confidentiality issues.
However, here is the code from the example I follow. I basically need to change rollups.whatever to give decimal places. The "11" in sum(11) here refers to a "column index".
window.onload = function() {
var Hypergrid = fin.Hypergrid;
var drillDown = Hypergrid.drillDown;
var TreeView = Hypergrid.TreeView;
var GroupView = Hypergrid.GroupView;
var AggView = Hypergrid.AggregationsView;
// List of properties to show as checkboxes in this demo's "dashboard"
var toggleProps = [{
label: 'Grouping',
ctrls: [
{ name: 'treeview', checked: false, setter: toggleTreeview },
{ name: 'aggregates', checked: false, setter: toggleAggregates },
{ name: 'grouping', checked: false, setter: toggleGrouping}
]
}
];
function derivedPeopleSchema(columns) {
// create a hierarchical schema organized by alias
var factory = new Hypergrid.ColumnSchemaFactory(columns);
factory.organize(/^(one|two|three|four|five|six|seven|eight)/i, { key: 'alias' });
var columnSchema = factory.lookup('last_name');
if (columnSchema) {
columnSchema.defaultOp = 'IN';
}
//factory.lookup('birthState').opMenu = ['>', '<'];
return factory.schema;
}
var customSchema = [
{ name: 'last_name', type: 'number', opMenu: ['=', '<', '>'], opMustBeInMenu: true },
{ name: 'total_number_of_pets_owned', type: 'number' },
{ name: 'height', type: 'number' },
'birthDate',
'birthState',
'employed',
{ name: 'income', type: 'number' },
{ name: 'travel', type: 'number' }
];
var peopleSchema = customSchema; // or try setting to derivedPeopleSchema
var gridOptions = {
data: people1,
schema: peopleSchema,
margin: { bottom: '17px' }
},
grid = window.g = new Hypergrid('div#json-example', gridOptions),
behavior = window.b = grid.behavior,
dataModel = window.m = behavior.dataModel,
idx = behavior.columnEnum;
console.log('Fields:'); console.dir(behavior.dataModel.getFields());
console.log('Headers:'); console.dir(behavior.dataModel.getHeaders());
console.log('Indexes:'); console.dir(idx);
var treeView, dataset;
function setData(data, options) {
options = options || {};
if (data === people1 || data === people2) {
options.schema = peopleSchema;
}
dataset = data;
behavior.setData(data, options);
idx = behavior.columnEnum;
}
// Preset a default dialog options object. Used by call to toggleDialog('ColumnPicker') from features/ColumnPicker.js and by toggleDialog() defined herein.
grid.setDialogOptions({
//container: document.getElementById('dialog-container'),
settings: false
});
// add a column filter subexpression containing a single condition purely for demo purposes
if (false) { // eslint-disable-line no-constant-condition
grid.getGlobalFilter().columnFilters.add({
children: [{
column: 'total_number_of_pets_owned',
operator: '=',
operand: '3'
}],
type: 'columnFilter'
});
}
window.vent = false;
//functions for showing the grouping/rollup capabilities
var rollups = window.fin.Hypergrid.analytics.util.aggregations,
aggregates = {
totalPets: rollups.sum(2),
averagePets: rollups.avg(2),
maxPets: rollups.max(2),
minPets: rollups.min(2),
firstPet: rollups.first(2),
lastPet: rollups.last(2),
stdDevPets: rollups.stddev(2)
},
groups = [idx.BIRTH_STATE, idx.LAST_NAME, idx.FIRST_NAME];
var aggView, aggViewOn = false, doAggregates = false;
function toggleAggregates() {
if (!aggView){
aggView = new AggView(grid, {});
aggView.setPipeline({ includeSorter: true, includeFilter: true });
}
if (this.checked) {
grid.setAggregateGroups(aggregates, groups);
aggViewOn = true;
} else {
grid.setAggregateGroups([], []);
aggViewOn = false;
}
}
function toggleTreeview() {
if (this.checked) {
treeView = new TreeView(grid, { treeColumn: 'State' });
treeView.setPipeline({ includeSorter: true, includeFilter: true });
treeView.setRelation(true, true);
} else {
treeView.setRelation(false);
treeView = undefined;
delete dataModel.pipeline; // restore original (shared) pipeline
behavior.setData(); // reset with original pipeline
}
}
var groupView, groupViewOn = false;
function toggleGrouping(){
if (!groupView){
groupView = new GroupView(grid, {});
groupView.setPipeline({ includeSorter: true, includeFilter: true });
}
if (this.checked){
grid.setGroups(groups);
groupViewOn = true;
} else {
grid.setGroups([]);
groupViewOn = false;
}
}
you may try:
(rollups.sum(11)).toFixed(2)
enclosing number in parentheses seems to make browser bypass the limit that identifier cannot start immediately after numeric literal
edited #2:
//all formatting and rendering per cell can be overridden in here
dataModel.getCell = function(config, rendererName) {
if(aggViewOn)
{
if(config.columnName == "total_pets")
{
if(typeof(config.value) == 'number')
{
config.value = config.value.toFixed(2);
}
else if(config.value && config.value.length == 3 && typeof(config.value[1]) == 'number')
{
config.value = config.value[1].toFixed(2);
}
}
}
return grid.cellRenderers.get(rendererName);
};

How can I reduce cyclomatic complexity from this piece of code?

I'm refactoring some legacy code. I get error from jshint about cyclomatic complexity which I'm trying to figure out how to fix the warning. The code is in node.js so anything in JavaScript is very much welcome.
if (rawObj.title) {
formattedObj.name = rawObj.title;
}
if (rawObj.urls && rawObj.urls.web) {
formattedObj.url = rawObj.urls.web.project;
}
if (rawObj.photo) {
formattedObj.image = rawObj.photo.thumb;
}
if (rawObj.category) {
formattedObj.category = rawObj.category.name;
}
It's really just checking if the property exists and map to a new object.
Kind of late to the party but you (or others looking for ways to reduce cyclomatic-complexity) could go with an approach like this. It's kind of like the strategy pattern. Depending if you can or can't use ES6, will determine which setRawObjProp you should use.
function setFormObjName () {
formattedObj.name = rawObj.title;
console.log(arguments.callee.name,formattedObj);
}
function setFormObjURL () {
formattedObj.url = rawObj.urls.web.project;
console.log(arguments.callee.name,formattedObj);
}
function setFormObjImage () {
formattedObj.image = rawObj.photo.thumb;
console.log(arguments.callee.name,formattedObj);
}
function setFormObjCat () {
formattedObj.category = rawObj.category.name;
console.log(arguments.callee.name,formattedObj);
}
function setRawObjProp(obj) {
var objectMap = new Map();
objectMap
.set('string1', setFormObjName)
.set('string2', setFormObjURL)
.set('string3', setFormObjImage)
.set('string4', setFormObjCat);
if (objectMap.has(obj)) {
return objectMap.get(obj)();
}
else {
console.log('error', obj);
}
}
/*
function setRawObjProp2(obj) {
var objectMap = {
'string1': setFormObjName,
'string2': setFormObjURL,
'string3': setFormObjImage,
'string4': setFormObjCat,
};
if (objectMap.hasOwnProperty(obj)) {
return objectMap.get(obj)();
}
else {
console.log('error', obj);
}
}
*/
var rawObj = {
title: 'string1',
urls: {
app: {
project: 'some thing'
},
web: {
project: 'string2'
}
},
photo: {
large: 'large',
thumb: 'string3'
},
category: {
name: 'string4',
type: 'some type',
id: 12345
}
},
formattedObj = {
title: '',
urls: {
web: {
project: ''
}
},
photo: {
thumb: ''
},
category: {
name: ''
}
};
setRawObjProp('string1');
/* setRawObjProp2('string1') */

Windows Azure + DevExrpess (PhoneJs) getting ToDoList (Standart Sample)

I'm starting to learn and azure phonejs.
Todo list get through a standard example:
$(function() {
var client = new WindowsAzure.MobileServiceClient('https://zaburrito.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
// Read current data and rebuild UI.
// If you plan to generate complex UIs like this, consider using a JavaScript templating library.
function refreshTodoItems() {
var query = todoItemTable.where({ complete: false });
query.read().then(function(todoItems) {
var listItems = $.map(todoItems, function(item) {
return $('<li>')
.attr('data-todoitem-id', item.id)
.append($('<button class="item-delete">Delete</button>'))
.append($('<input type="checkbox" class="item-complete">').prop('checked', item.complete))
.append($('<div>').append($('<input class="item-text">').val(item.text)));
});
$('#todo-items').empty().append(listItems).toggle(listItems.length > 0);
$('#summary').html('<strong>' + todoItems.length + '</strong> item(s)');
}, handleError);
}
function handleError(error) {
var text = error + (error.request ? ' - ' + error.request.status : '');
$('#errorlog').append($('<li>').text(text));
}
function getTodoItemId(formElement) {
return $(formElement).closest('li').attr('data-todoitem-id');
}
// Handle insert
$('#add-item').submit(function(evt) {
var textbox = $('#new-item-text'),
itemText = textbox.val();
if (itemText !== '') {
todoItemTable.insert({ text: itemText, complete: false }).then(refreshTodoItems, handleError);
}
textbox.val('').focus();
evt.preventDefault();
});
// Handle update
$(document.body).on('change', '.item-text', function() {
var newText = $(this).val();
todoItemTable.update({ id: getTodoItemId(this), text: newText }).then(null, handleError);
});
$(document.body).on('change', '.item-complete', function() {
var isComplete = $(this).prop('checked');
todoItemTable.update({ id: getTodoItemId(this), complete: isComplete }).then(refreshTodoItems, handleError);
});
// Handle delete
$(document.body).on('click', '.item-delete', function () {
todoItemTable.del({ id: getTodoItemId(this) }).then(refreshTodoItems, handleError);
});
// On initial load, start by fetching the current data
refreshTodoItems();
});
and it works!
Changed for the use of phonejs and the program stops working, even mistakes does not issue!
This my View:
<div data-options="dxView : { name: 'home', title: 'Home' } " >
<div class="home-view" data-options="dxContent : { targetPlaceholder: 'content' } " >
<button data-bind="click: incrementClickCounter">Click me</button>
<span data-bind="text: listData"></span>
<div data-bind="dxList:{
dataSource: listData,
itemTemplate:'toDoItemTemplate'}">
<div data-options="dxTemplate:{ name:'toDoItemTemplate' }">
<div style="float:left; width:100%;">
<h1 data-bind="text: name"></h1>
</div>
</div>
</div>
</div>
This my ViewModel:
Application1.home = function (params) {
var client = new WindowsAzure.MobileServiceClient('https://zaburrito.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
var toDoArray = ko.observableArray([
{ name: "111", type: "111" },
{ name: "222", type: "222" }]);
var query = todoItemTable.where({ complete: false });
query.read().then(function (todoItems) {
for (var i = 0; i < todoItems.length; i++) {
toDoArray.push({ name: todoItems[i].text, type: "NEW!" });
}
});
var viewModel = {
listData: toDoArray,
incrementClickCounter: function () {
todoItemTable = client.getTable('todoitem');
toDoArray.push({ name: "Zippy", type: "Unknown" });
}
};
return viewModel;
};
I can easily add items to the list of programs, but from the server list does not come:-(
I am driven to exhaustion and can not solve the problem for 3 days, which is critical for me!
Specify where my mistake! Thank U!
I suggest you use a DevExpress.data.DataSource and a DevExpress.data.CustomStore instead of ko.observableArray.
Application1.home = function (params) {
var client = new WindowsAzure.MobileServiceClient('https://zaburrito.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
var toDoArray = [];
var store = new DevExpress.data.CustomStore({
load: function(loadOptions) {
var d = $.Deferred();
if(toDoArray.length) {
d.resolve(toDoArray);
} else {
todoItemTable
.where({ complete: false })
.read()
.then(function(todoItems) {
for (var i = 0; i < todoItems.length; i++) {
toDoArray.push({ name: todoItems[i].text, type: "NEW!" });
}
d.resolve(toDoArray);
});
}
return d.promise();
},
insert: function(values) {
return toDoArray.push(values) - 1;
},
remove: function(key) {
if (!(key in toDoArray))
throw Error("Unknown key");
toDoArray.splice(key, 1);
},
update: function(key, values) {
if (!(key in toDoArray))
throw Error("Unknown key");
toDoArray[key] = $.extend(true, toDoArray[key], values);
}
});
var source = new DevExpress.data.DataSource(store);
// older version
store.modified.add(function() { source.load(); });
// starting from 14.2:
// store.on("modified", function() { source.load(); });
var viewModel = {
listData: source,
incrementClickCounter: function () {
store.insert({ name: "Zippy", type: "Unknown" });
}
};
return viewModel;
}
You can read more about it here and here.

Categories