Ember Latest

The latest build of Ember.

HTML

<script src="http://builds.emberjs.com/handlebars-1.0.0.js"></script>
<script src="http://builds.emberjs.com/ember-latest.js"></script>
<script type="text/x-handlebars" data-template-name="application">
    {{#search-container action='search' content=filteredContent}}
        {{search-input}}
        {{search-results row=App.PersonView}}
    {{/search-container}}
</script>

<script type="text/x-handlebars" data-template-name="person">
   <li>{{fullName}}</li>
</script>

<script type="text/x-handlebars" data-template-name="components/search-container">
   Search Container
   {{yield}}
</script>

<script type="text/x-handlebars" data-template-name="components/search-input">
   {{input type='text' value=value placeholder='Search Term'}}
</script>

<script type="text/x-handlebars" data-template-name="components/search-results">
    <ul>{{#each person in content}}
        {{view row context=person}}
        {{/each}}</ul>
</script>

CSS

html, body { margin: 10px; font-family: 'HelveticaNeue-Thin'; }
ul { padding: 0; margin: 0; }
ul li { padding: 5px; background: #f1f1f1; margin: 1px 0; }
input { padding: 8px; border: 1px solid #ddd; margin: 10px 0; }

JavaScript

App = Ember.Application.create({});

var store = [
    { fullName: 'Kris Selden' },
    { fullName: 'Luke Melia' },
    { fullName: 'Formerly Alex Matchneer' }
];

App.ApplicationRoute = Ember.Route.extend({
  model: function() {
      return store;
  },
    setupController: function(controller, model) {
        this._super(controller, model);
        controller.set('filteredContent', model);
    }
});

App.PersonView = Ember.View.extend({
    templateName: 'person'
});

App.ApplicationController = Ember.ArrayController.extend({
  filteredContent: [],
  actions: {
      search: function(searchTerm) {
          searchTerm = searchTerm.toLowerCase();
          var filtered = this.get('content').filter(function(model) {
              return Ember.get(model, 'fullName').toLowerCase().indexOf(searchTerm) !== -1;
          });
          
          this.set('filteredContent', filtered);
      }
  }
});

App.SearchContainerComponent = Ember.Component.extend({
    layoutName: 'components/search-container',
    
    inputComponent: null,
    resultsComponent: null,
    
    filterText: '',
    content: [],
    
    filterTextChanged: function() {
        Ember.run.debounce(this, 'triggerSearch', 500);
    }.observes('filterText'),
    
    triggerSearch: function() {
        this.sendAction('action', this.get('filterText'));
    },
    
    registerInput: function(input) {
        this.set('inputComponent', input);
        Ember.Binding.from('parentView.filterText').to('value').connect(input);
    },
    
    registerResults: function(results) {
        this.set('resultsComponent', results);
        Ember.Binding.from('parentView.content').to('content').connect(results);
    }
});

App.SearchInputComponent = Ember.Component.extend({
    value: null,
    onInsert: function() {
        this.get('parentView').registerInput(this);
    }.on('didInsertElement')
});

App.SearchResultsComponent = Ember.Component.extend({
    content: null,
    onInsert: function() {
       ...