I'm trying to use the Knockout Concurrency plugin in my project, and I'm currently fiddling with the example code, but I'm not getting it to work:
https://github.com/AndersMalmgren/Knockout.Concurrency/wiki/Getting-started
ViewModel = function() {
this.name = ko.observable("John").extend({ concurrency: true});
this.children = [{ name: ko.observable("Jane").extend({concurrency: true })}, { name: ko.observable("Bruce").extend({concurrency: true })}];
this.getData = function() {
//Simulate backend data
var data = { name: "John Doe", children: [{ name: "Jane Doe"},{ name: "Bruce Wayne"}, { name: "New row"}]};
new ko.concurrency.Runner().run(this, data);
}
}
ko.applyBindings(new ViewModel());
http://jsfiddle.net/rCVk4/3/
Nothing happens and the newly added item is not tracked by the plugin, does anyone know why?
Thanks for trying out my Plugin, really fast too, I uploaded the code today!
The plugin does indeed support tracking of deleted and added rows. But for it to know which rows are what It needs you to supply it with a mapper
var mappings = {
children: {
key: function(item) {
return ko.utils.unwrapObservable(item.id);
},
create: function(data) {
return { id: data.id, name: data.name };
}
}
};
The name children corresponds to the name of the array.
The Key method is used to identify the property used as an identifier.
The Create method is used to create new rows (Added rows).
You can download the MVC3 sample from Github for a fully featured Demo, also please try out this Fiddle
http://jsfiddle.net/7atZT/
Related
I'm new to jsonapi and how the structure works and trying to get a relationship to load properly. I'm expecting ember-data to follow provided url's in the relationship.links of my objects to fetch the required information but I'm getting unexpected results.
I have Users, Territories, and a User/Territory relationship defined like this:
// User Model
const UserModel = DS.Model.extend({
username: DS.attr('string'),
territories: DS.hasMany('user-territories')
}
// Territory Model
const TerritoryModel = DS.Model.extend({
name: DS.attr('string')
}
// User-Territory Model
const UserTerritoryModel = DS.Model.extend({
notes: DS.attr('string'),
startDate: DS.attr('date'),
user: DS.belongsTo('user'),
territory: DS.belongsTo('territory')
}
I then have mock data (using http-mock) that looks like this:
// api/users/
data: {
type: "users",
id: 1,
attributes: {
username: "thisIsMyUsername"
}
},
relationships: {
territories: {
links: {
self: "http://localhost:4200/api/users/1/territories"
}
}
}
// api/users/1/territories
data: {
type: "user-territories",
id: 1,
attributes: {
notes: "This is a note",
startDate: "2017-01-01"
}
},
relationships: {
user: {
link: {
self: "http://localhost:4200/api/users/1"
}
},
territory: {
link: {
self: "http://localhost:4200/api/territories/1"
}
}
}
// api/territories/1
data: {
type: "territories",
id: 1,
attributes: {
name: "Territory #1"
}
}
In my User route, I want to request the UserModel and have access to the UserTerritory Relationship data and the Territory itself. The api calls are not what I expect though:
this.get('store').findRecord('user', 1, { include: "territories" });
EXPECTED:
api/users/1
api/users/1/territories
ACTUAL:
api/users/1
api/users/1?include=territories
If I call the user-territories model I get this:
EXPECTED:
api/users/1/territories
ACTUAL:
api/user-territories/1
If you use included, ember-data basically thinks you want to tell the server to side-load data. If you return a links, just resolve the relationship. However the relationships have to be inside the data. Also the self link is for the relationship itself, to return the data use related.
So first you do something like user = store.findRecord('user', '1'), this will fetch to api/users/. Then you should return something like this:
// api/users/
{
data: {
type: "users",
id: 1,
attributes: {
username: "thisIsMyUsername"
}
relationships: {
territories: {
links: {
related: "http://localhost:4200/api/users/1/territories"
}
}
}
}
}
Next you do user.get('territories'). This will return a promise, and fetch http://localhost:4200/api/users/1/territories, or whatever was inside that related link. However know, what ember-data will expect you to return user-territories here, because thats what you specified with territories: DS.hasMany('user-territories'). You should know what you directly can model an many-to-many relationship in ember-data without a third table.
I run into a problem when use Ember-data to save a model. The JSON structure for my model looks like:
{ post: {
id: 1,
name: 'post-1',
trigger: ['trigger-1', 'trigger-2'],
data: ['data-1', 'data-2']
}
}
Because 'data' and 'trigger' are reserved keywords for DS.Model, I created a mapping and renamed them to sc_data and sc_trigger as suggestion by Jurre using
Application.SERIALIZATION_KEY_MAPPINGS = {
'sc_data': 'data',
'sc_trigger': 'trigger'
};
Application.ApplicationSerializer = DS.ActiveModelSerializer.extend({
keyForAttribute: function (attr) {
if (Application.SERIALIZATION_KEY_MAPPINGS.hasOwnProperty(attr)) {
return Application.SERIALIZATION_KEY_MAPPINGS[attr];
} else {
return this._super(attr);
}
}
});
So my model for post looks like:
Application.Post = DS.Model.extend({
name: DS.attr('string'),
sc_trigger: DS.attr(),
sc_data: DS.attr()
});
the sc_trigger and sc_data are renmaed mapping for data and trigger.
It all worked fine when use this.store.find('post') and this.store.find('post', 1), i.e. GET calls. When I try to create a record using this.store.createRecord('post'), it creates a record with the correct attribute name sc_data and sc_trigger.
var newPost = this.store.create('post', {
name: 'test post',
sc_data: [],
sc_trigger: []
})
And the serialize function interprets the mapping correctly as well. newPost.serialize() returns
{
name: 'test post',
data: [],
trigger: []
}
But when I call newPost.save(), in the HTTP request body of the POST call, data and trigger field is missing. It only has
{
name: 'test post'
}
I have no idea why newPost.save() doesn't generate the correct request body when serialize() is working just fine.
Update
I managed to get around this by removing the keyForAttribute mapping and using
Application.ApplicationSerializer = DS.ActiveModelSerializer.extend({
attrs: {
sc_data: {key: 'data'},
sc_trigger: {key: 'trigger'}
}
});
This seems to be the suggested way to handle data with reserved keywords.
Which ember data version and emberjs version are you using?
Try saving with id like-
var newPost = this.store.create('post', {
id:1
name: 'test post',
sc_data: [],
sc_trigger: []
});
Save and create always expects id. So it's better to save/create record with id.
I'm trying to get my head around Ember Data by creating a simple attendance app. The goal is to have a student type in their name and hit submit, creating a new Attendance record that is associated with that student. Here's what I've done to make it work:
App.Student = DS.Model.extend({
name: DS.attr('string'),
attendances: DS.hasMany('attendance', { async: true })
});
App.Attendance = DS.Model.extend({
student: DS.belongsTo('student', { async: true }),
...
});
--
App.NewAttendanceController = Ember.ObjectController.extend({
content: {},
actions: {
createAttendance: function() {
var studentName = this.get('name');
this.store.find('student', { name: studentName })
.then(function(fulfilledPromise) {
var student = fulfilledPromise.get('firstObject');
var attendance = fulfilledPromise.store.createRecord('attendance', {
time: moment(),
student: student
});
attendance.save();
});
}
}
});
In the createAttendance action I first grab the inputted name, find matching student records, wait for the fulfilled promise before grabbing the first student, then create a new attendance record with it's student property set to the grabbed student record and save it.
So this works, but it feels really strange. I'm hoping someone could show me a better way to go about selecting records and making associations in Ember Data.
I want to show some details on to Sencha Touch 2.3.1 DataView.
Actual Data to be loaded will come later to the DataView object creation.
I am not using Store proxy, but I have my own existing HTTP Request API for getting the JSON data. So once I get the data, I am creating a DataModel and adding to Store.
When I debug the code, I see it is adding and Store is populated with Data.
Now I am getting the DataView object with Ext.getCmp("") and setting the Store.
When I see the DataView object, I see the store (_store) containing the data (_data) in it.
But still the DataView is not populated with the datails.
Please help me in this context
My DataModel:
Ext.define('AlbumsListDM', {
extend: 'Ext.data.Model',
config: {
fields: [
"user",
"title",
"subtitle",
"image"
]
}
});
My Store:
Ext.define('AlbumsListStore', {
extend: 'Ext.data.Store',
config: {
model: 'AlbumsListDM',
autoLoad: true
}
});
My DataView:
Ext.define(APP_NAME+'.view.AlbumsList', {
extend: 'Ext.DataView',
id: 'viewAlbumsListID',
requires: ['AlbumsListDM'],
config: {
width:'100%',
height:'100%',
layout: 'fit',
items: [{
xtype: 'dataview',
scrollable: true,
inline: true,
cls: 'dataview-inline',
itemTpl: new Ext.XTemplate('<div class="img" style="background-image: url({image});">{title}</div>')
}]
}
});
My Construction of store and updating DataView:
Ext.create('AlbumsListStore', { id: 'AlbumsListStoreID' });
var albumsList = myJsonData;
var albumsListStore = Ext.getStore('AlbumsListStoreID');
var count = albumsList.length;
for(var index = 0; index < count; index++) {
albumsListStore.add(Ext.create('AlbumsListDM', albumsList[index]));
}
var viewAlbumsList = Ext.getCmp("viewAlbumsListID");
viewAlbumsList.setStore(albumsListStore);
Thanks
Siva
Im using Ember v1.0.0, Ember-Data v1.0.0-beta.3 and building using Ember-tools.
Inside my order_controller, I've got an action called: delivered. Once triggered, I want to make some changes to the current object (no problems here) -- but I also want to query an object from this same model and make some changes to it.
Heres my ObjectController:
var OrderController = Ember.ObjectController.extend({
actions: {
edit: function(){
this.transitionToRoute('order.edit');
},
delivered: function(){
// orders are sorted by "sequence" attr.
var current_sequence = this.get('sequence');
// find the next order in pipeline
var next_sequence = current_sequence+=1;
// HERE is the challenge!
var next_order = App.Order.find({sequence: next_sequence});
this.set('up_next', false);
next_order.set('up_next', true);
this.transitionToRoute('order', next_order.id)
}
}
});
module.exports = OrderController;
Im using FIXTURES:
Order.FIXTURES = [
{
id: 1,
name: "John Doe",
email: "john#doe.com",
telephone: "263663636",
address: "123 Example Rd.",
......
sequence: 4,
done: false,
up_next: false
},
Basically Im looking for a way to query records from inside the ObjectController with more specific attributes than just ID.
Thanks!
// Find all the records, find returns a promise
var promise = this.get('store').find('order');
this.set('up_next', false);
next_order.set('up_next', true);
// once the promise is resolved
promise.then(function(records){
// filter out the first item to satisfy the method passed into it
// http://emberjs.com/api/classes/Ember.Array.html#method_find
var filteredRecord = records.find( function(record){ return record.get('sequence')==sequenceNo;});
this.transitionToRoute('order', next_order)
}