Ember Data Embedded Records

by amindunited

HTML

<link rel="stylesheet" href="https://rawgithub.com/ducksboard/gridster.js/master/dist/jquery.gridster.css" />

<script type="text/x-handlebars" data-template-name="application">
    <header>
        <h1>App</h1>
    </header>
    <div class="fileTreeWrap">
        <hr/>
        {{#each filesys in content}}
        {{file-tree root=filesys}}
        {{/each}}
        <hr/>
    </div>
    <div class="bodyMain">
        {{file-tree-file-editor-too files=view.openedFiles}}
    </div>
</script>

<script type="text/x-handlebars" data-template-name="components/file-tree">
    ?
    {{log "Magoo"}}
    {{log root}}
    {{file-tree-directory dir=root}}
</script>
<script type="text/x-handlebars" data-template-name="components/file-tree-directory">
    <div class="folder">{{dir.name}}</div>
    <ul>
    {{#each directory in view.dir.directories}}
        <li>{{file-tree-directory dir=directory}}</li>
    {{/each}}
    </ul>
    <ul>
    {{#each file in view.dir.files}}
        <li>{{file-tree-file file=file}}</li>
    {{/each}}
    </ul>
    
</script>
<script type="text/x-handlebars" data-template-name="components/file-tree-file">
    <div class="file">{{view.file.name}}</div>
</script>
<script type="text/x-handlebars" data-template-name="components/file-tree-file-editor">
    {{#each directory in root_dir.directories}}
        {{file-tree-file-editor root_dir=directory}}
    {{/each}}
    <ul>
    {{#each file in root_dir.files}}
        {{#if file.editing}}
            {{file-tree-file-editor-tab file=file selected="selected"}}
        {{/if}}
    {{/each}}
    </ul>
</script>

<script type="text/x-handlebars" data-template-name="components/file-tree-file-editor-too">
    <h2>File Tree Editor 2</h2>
    <ul class="tabsList">
    {{#each file in files}}
        {{file-tree-file-editor-tab file=file selected="selected"}}
    {{/each}}
    </ul>
    {{#each file in files}}
        {{#if file.active}}
            {{file-tree-file-editor-tab-content file=file...

CSS

.clearfix {
    content:"";
    display:table;
    clear:both;
}
pre {
    height: 200px;
    width: 100%;
    display: block;
}
.fileTreeWrap {
    max-width: 32%;
    display: inline-block;
    overflow: auto;
}

.fileTreeWrap ul {
    margin-left: 1.3em;
    border-left: dashed 1px black;
}
.fileTreeWrap ul li {
}


[draggable] {
    
  -moz-user-select: none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  user-select: none;
  /* Required to make elements draggable in old WebKit */
  -khtml-user-drag: element;
  -webkit-user-drag: element;
}
.bodyMain {
    width: 65%;
    min-height: 500px;
    border: solid 1px #666666;
    border-radius: 5px;
    display: inline-block;
    vertical-align: top;
    
}

.bodyMain .tabsList {
    margin-top: 0;
    margin-bottom: 0;
    list-style: none;
    padding: 0;
    content:"";
    display:table;
    clear:both;
}

.bodyMain .active.tab {
    background-color: rgba(201,201,201,1);
    color: rgba(249, 184, 53, 1);/*rgba(41, 193, 60, 1);*/
    text-shadow: 1px 1px 1px rgba(0, 0, 0, .5);
}

.bodyMain .tab {
    max-width: 25%;
    min-width: 6em;
    list-style: none;
    display: inline-block;
    text-overflow: ellipsis;
    overflow: hidden;
    padding: 5px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    background-color: rgba( 135,135, 135,1);
    float: left;
    color: white;
    text-shadow: 1px 1px 1px rgba(0, 0, 0, 1);
}

.bodyMain .tabContent {
    width: 100%;
    background-color: rgba(201,201,201,1);
}


.folder:before {
    font-family: 'entypo';
    content: '\e69f';
    margin-right: 5px;
}
.file:before {
    font-family: 'entypo';
    content: '\e699';
    margin-right: 5px;
}

/* As hex codes */

.color-primary-0 { color: #C9C9C9 }	/* Main Primary color */
.color-primary-1 { color: #C9C9C9 }
.color-primary-2 { color: #F93F35 }
.color-primary-3 { color: #C9C9C9 }
.color-primary-4 { color: #F93F35 }

.color-secondary-1-0 { color: #C9C9C9 }	/* Main Secondary color (1)...

JavaScript

App = Em.Application.create();

App.ApplicationRoute = Em.Route.extend({
    model: function(){
        console.log('hit the moel function');
        var mmm = this.store.find('filesystem');
        return mmm;
    }
    
});

/* Originally the EmbeddedRecordsMixin only worked with the ActiveModelAdapter...that might be fixed now... */
App.ApplicationAdapter = DS.ActiveModelAdapter.extend();

/* Serialize each model that has embedded records....just set ['propertyName']: {embedded:'always'} */
App.FilesystemSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
    attrs: {
        files: {embedded: 'always'},
        directories: {embedded: 'always'}
    }
});

App.DirectorySerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
    attrs: {
        files: {embedded: 'always'},
        directories: {embedded: 'always'}
    }
});

/* 
    define a model for each record...
    
*/

App.Filesystem = DS.Model.extend({
    name: DS.attr(),
    files: DS.hasMany('file'),
    directories: DS.hasMany('directory')
});
//Embedded ones too!   :)
App.Directory = DS.Model.extend({
    name: DS.attr(),
    files: DS.hasMany('file'),
    directories: DS.hasMany('directory')
});

App.File = DS.Model.extend({
    name: DS.attr(),
    contents: DS.attr()
});
App.ApplicationController = Em.Controller.extend({

});
App.ApplicationView = Em.View.extend({
    openedFiles: [],
    didInsertElement: function(){
        var self = this;
        $('.bodyMain').on('dragenter', function(e){
            e.preventDefault();
            e.stopPropagation();
        });
        $('.bodyMain').on('dragover', function(e){
            e.preventDefault();
            e.stopPropagation();
        });
        $('.bodyMain').on('drop', function(e){
            var viewId = e.originalEvent.dataTransfer.getData('Text'),
            view = Ember.View.views[viewId];
            view.get('file').set('editing', true);
           ...