The Making of the Model State Explorer

Published on Jan 01, 2016

A whirlwind tour of what I think is cool about the Model State Explorer app.

Some points touched on: ember-cli-mirage in production, custom computed property macros, inverse relationships, pagefront hosting, and the recursive folder structure (and thus recursive nesting of components). There is also some discussion of more basic Ember topics.

CORRECTION: The computed property macro works, but the flags.${dependentKey} key is unnecessary. I noticed this when I realized flags is an array thus wouldn’t have a ${dependentKey} attribute.


Links

Code

It's really hard to summarize something as wide-ranging as this screencast. Why not peruse the github repository?

Transcript

Last week, I introduced the Ember Data 2.0 Model State Explorer, and we learned a lot from it. In this episode, I’m going to be showing some of the tricks I used to make this, and it'll just be a really quick run-through showing you some cool techniques that you can use in your own apps. If you want to follow along, this is the URL for playing with it, and this is the GitHub project. And I’ll provide links to these in the show notes.

If you see anything in this presentation that you want more details on, tell me in the comments and I’ll take that into account when I’m deciding which topics to cover. Alright, now let’s get to the code.

So first, I wanted to just have the front end. I didn’t want to have to deploy a backend. So I used ember-cli-mirage. It’s usually used just for development and testing, but I set it to be enabled in production as well.

And so then, this is in our mirage/fixtures/states.js file, and this has all the data for our states. We’ll go over the state model and then come back to this.

So the state, it has the name, and then it has for the parents and the children, and these are relationships to other states. And they do exactly what you would expect. They are inverses of each other and you can have multiple children but only one parent.

Then you also have flags which is... it’s given no transforms, so it’s just passed in as an array.

And then we have this series of is blah-blah-blah, so isDeleted, isDirty, isEmpty. So these are different states, and they’re all done based on the isX function which creates a computed property. So we’ve basically created our own computed property macro. And what that does is it looks for that flag... well, it takes a key and it looks for that on the flags, and if the flags include that, then it returns true. So isDirty is true if dirty is included in the flags array.

So going back to the states fixtures, we have the name, and then we have the parent and children, and we’re doing that based on the id, and we’re assigning these ids manually so that we’re able to create these relationships in the fixtures. Finally we have the flags array.

Now it’s important to note some versions on these. I’m using the 0.1.x version of ember-cli-mirage. There’s a 0.2 version and Beta, but the documentation isn’t quite there as of the making of this video. So some of this may change in the near future, but the basic idea behind it shouldn’t.

And by the same token, I just created an ember-cli-project and I took the versions of Ember and Ember Data that it gave me, which were 1.13.x. So this file may change. This file should stay pretty much the same since most of the large changes in Ember Data weren’t from 1.13 to 2.0. They’re from Beta to 1.13.

Alright, now moving on, let’s look at our templates and controllers. Our application route, it just finds all of the states, and then the application/index controller, it gets all the rootStates which will just be array of one, and it grabs the first one off there. So we have the rootState.

So then in the handlebars, it feeds all this into tree-state. It feeds in the rootState as well as the highlightedFlag. Before we get into the details of the tree-state, let’s go over the highlightedFlag. This is the part that’s on the bottom here, ‘Highlight by Flag’.

So what it’s doing is it’s looping through all the possible flags, and these are defined here on the state model. And then for each of those, it’s giving it a button with the action of highlightFlag, and it highlights this button if the flag itself is currently highlighted.

And there’s also a Reset button. And that action, highlightFlag, it sets the highlightedFlag property to whatever is passed in. Alright, and so that is also passed in to the tree-state component as highlightedFlag. Now the tree-state component is where most of the action is, not in the JavaScript. It’s just a basic toggling of the isExpanded property but in the handlebars.

So we have our margin-left to 20 pixels, and that’s for each of them, and that’s how we get this nice nested look, because as you’ll see, within this, each of the children of the state, it creates another tree-state for it, and so on and so on until they run out of children.

And so this entire tree is all started from the root state, and then it just grabs the root state’s four children, and each of those it grabs their children and displays them.

This is the basics of doing a folder structure, and there are quite a few instances where you might want to use this, so keep this in mind.

Alright, so that’s how we do the folder structure here. Here is where we show the actual state itself. So we have a different class if it’s expanded, and if you click anywhere on it, it’ll toggle the expansion.

So if it’s not expanded, then it’s easy. It’s just a span containing the shortName of the state, and the shortName is basically gotten by splitting it along the dots and just getting the lastObject.

So this shortName is uncommitted. The fullName is root.deleted.uncommitted. So it’s showing that, and if the state has a highlightedFlag, then it’ll have highlightedState and turn it yellow.

Then if it is expanded, it’ll once again show the state.name with the full name this time, and then it’ll loop through all the possible flags and display them all, but gray out the ones that are not currently there using the unless helper, so it grays out the ones that are false.

So that’s pretty much it for the code. One last thing, I also used ember-page-front. This add-on lets me host my files on page front. And I’ve been really enjoying the experience so far, I might make a screencast all about that.

So that’s it for today. If you have any parts of this that you really enjoyed and want to see more of, go ahead and talk to me in the comments, and if you want to see more things where I just walked through a bunch of code instead of diving deep into one issue, go ahead and tell me that too. Thanks and I’ll see you next time.

Subscribe to our mailing list