Skip to content

Instantly share code, notes, and snippets.

@tlint
Last active February 6, 2018 19:20
Show Gist options
  • Save tlint/da9ebbc54bfef40c9e59f3d6f58c475a to your computer and use it in GitHub Desktop.
Save tlint/da9ebbc54bfef40c9e59f3d6f58c475a to your computer and use it in GitHub Desktop.
Taylor's Twiddle
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Tays Twiddle',
init() {
const item1 = this.store.createRecord('primary-collection-item', {
id: 1,
urn: 'urn:item:1',
name: 'Taylor',
count: 25
});
this.store.createRecord('person-preferences', {
id: 1,
memberUrn: 'urn:item:1',
favoriteColor: 'Pink'
});
const item2 = this.store.createRecord('primary-collection-item', {
id: 2,
urn: 'urn:item:2',
name: 'Brian',
count: 24
});
this.store.createRecord('person-preferences', {
id: 2,
memberUrn: 'urn:item:2',
favoriteColor: 'Green'
});
const item3 = this.store.createRecord('primary-collection-item', {
id: 3,
urn: 'urn:item:3',
name: 'Michelle',
count: 23
});
this.store.createRecord('person-preferences', {
id: 3,
memberUrn: 'urn:item:3',
favoriteColor: 'Purple'
});
const item4 = this.store.createRecord('primary-collection-item', {
id: 4,
urn: 'urn:item:4',
name: 'Evan',
count: 26
});
this.store.createRecord('person-preferences', {
id: 4,
memberUrn: 'urn:item:4',
favoriteColor: 'Blue'
});
const item5 = this.store.createRecord('primary-collection-item', {
id: 5,
urn: 'urn:item:5',
name: 'Teddy',
count: 28
});
this.store.createRecord('person-preferences', {
id: 5,
memberUrn: 'urn:item:5',
favoriteColor: 'Orange'
});
const item6 = this.store.createRecord('primary-collection-item', {
id: 6,
urn: 'urn:item:6',
name: 'Will',
count: 27
});
this.store.createRecord('person-preferences', {
id: 6,
memberUrn: 'urn:item:6',
favoriteColor: 'Yellow'
});
this.store.createRecord('primary-collection', {
teamMembers: [item1, item2, item3, item4, item5, item6],
extraInfo: 'This is a list of team members names',
id: 1
});
}
});
import Ember from 'ember';
export default Ember.Controller.extend({
// This computed is a naive approach to solving the problem of displaying two separate data sets together, it does not address the fact of loading some data lazily
itemsShowing: Ember.computed('model.primaryCollection.teamMembers', 'model.secondaryCollection', 'index', function() {
const index = Ember.get(this, 'index');
const primaryCollection = Ember.get(this, 'model.primaryCollection.teamMembers')
const secondaryCollection = Ember.get(this, 'model.secondaryCollection')
const itemsShowing = [];
// For the index and index+1 of primaryCollection, create the new object to show with the data from secondary collection
for (let i = index; i <= index+1; i++) {
const firstId = primaryCollection.objectAt(i).get('urn')
const matchingEntity = secondaryCollection.find(preference => preference.get('memberUrn') === firstId)
const item = {
name: primaryCollection.objectAt(i).get('name'),
count: primaryCollection.objectAt(i).get('count'),
favoriteColor: matchingEntity.get('favoriteColor'),
}
itemsShowing.push(item);
}
return itemsShowing;
}),
index: 0,
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
memberUrn: attr('string'),
favoriteColor: attr('string')
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
urn: attr('string'),
name: attr('string'),
count: attr('number')
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
extraInfo: attr('string'),
teamMembers: hasMany('primary-collection-item')
});
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('my-route', { path: '/' });
});
export default Router;
import Ember from 'ember';
// The twiddle is displaying a list of team members from the primary-collection model with their count of marbles and their favorite color. Their favorite color does not live on the individual model with the member's name and marble count, it is loaded (eventually lazily) based off the member's id (to simplify, the models in this example all have ids that match the id in their urn)
// This twiddle is meant to illustrate two problems that are trying to be solved:
// 1. Displaying data from two collections together (this is naively attempted in the computed on the controller of this route)
// 2. When/how to lazy load the secondary data that only needs to be loaded when actually displayed in the template (Thispart is not addressed in the twiddle yet, the only place that seems appropriate is potentially the actions, but those don't contain the logic for which items are actually about to be displayed)
export default Ember.Route.extend({
model() {
const secondaryCollection = []
return this.store.findRecord('primary-collection', 1).then((result) => {
// In our example we will not be able to load all of the data points of the secondary data in the model, they need to be done only when shown to the user. But then will likely be done in groups as a batch_get to retrieve a group of favorite colors together based on a group of members ids being currently shown
Ember.get(result, 'teamMembers').forEach((item) => {
const itemId = Ember.get(item, 'id');
secondaryCollection.push(this.store.findRecord('person-preferences', itemId));
})
return {
primaryCollection: result,
secondaryCollection: secondaryCollection
}
})
},
actions: {
// Example actions for changing the list displayed on the screen, meant to mimic the sorting and paginiation that a list could have, in our use case we may need to also load the secondary data for the points that are about to be shown here?
next() {
const currentIndex = Ember.get(this, 'controller.index');
if (currentIndex < 4) {
Ember.set(this, 'controller.index', currentIndex + 2);
}
else {
Ember.set(this, 'controller.index', 0);
}
},
random() {
const randomFirst = Math.floor((Math.random() * 5));
Ember.set(this, 'controller.index', randomFirst);
}
},
});
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{outlet}}
<br>
<br>
<div>
<ul>
{{#each itemsShowing as |item|}}
<li> {{item.name}} has {{item.count}} marbles and their favorite color is: {{item.favoriteColor}} </li>
{{/each}}
</ul>
<button {{action "next"}}>
Next
</button>
<button {{action "random"}}>
Random
</button>
</div>
{
"version": "0.13.0",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.16.2",
"ember-template-compiler": "2.16.2",
"ember-testing": "2.16.2"
},
"addons": {
"ember-data": "2.16.3"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment