AngularJS Example:

by mhevery

HTML

<div ng-app="project">
  <h2>JavaScript Projects</h2>
  <div ng-view></div>



  <!-- CACHE FILE: project-list.html -->
  <script type="text/ng-template" id="project-list.html">
    <input type="text" ng-model="predicate" class="search-query"
           placeholder="Search" ng-model-instant>
    <table>
      <thead>
        <tr>
          <th>Project</th>
          <th>Description</th>
          <th><a href="#/new"><i class="icon-plus-sign"></i></a></th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="project in projects | filter:predicate | orderBy:'name'">
          <td>{{project.name}}</td>
          <td>{{project.description}}</td>
          <td>
            <a href="#/edit/{{project.objectId}}"><i class="icon-pencil"></i></a>
          </td>
        </tr>
      </tbody>
    </table>
  </script>



  <!-- CACHE FILE: project-edit.html -->
  <script type="text/ng-template" id="project-edit.html">
    <form name="myForm">
      <div class="control-group" ng-class="{error: myForm.name.$invalid}">
        <label>Name</label>
        <input type="text" name="name" ng-model="project.name" required
               class="span2" ng-model-instant>
        <span ng-show="myForm.name.$error.required" class="help-inline">
            Required</span>
      </div>
    
      <div class="control-group" ng-class="{error: myForm.site.$invalid}">
        <label>Website</label>
        <input type="url" name="site" ng-model="project.site" required
               class="span2" ng-model-instant>
        <span ng-show="myForm.site.$error.required" class="help-inline">
            Required</span>
        <span ng-show="myForm.site.$error.url" class="help-inline">
            Not a URL</span>
      </div>
    
      <label>Description</label>
      <textarea name="description" ng-model="project.description"
                ng-model-instant></textarea>
    
      <label>Created</label>
      <input type="text" name="site" disabled value="{{project.createdAt}}">
   ...

CSS

</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> 
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://code.angularjs.org/angular-1.0.0rc3.min.js"></script>
<style>

JavaScript

angular.module('project', ['parse']).

  config(function($routeProvider) {
    $routeProvider.when('/list',
      { controller: ProjectListCntl, template: 'project-list.html' });
    $routeProvider.when('/edit/:projectId',
      { controller: ProjectEditCntl, template: 'project-edit.html' });
    $routeProvider.when('/new',
      { controller: ProjectCreateCntl, template: 'project-edit.html' });

    $routeProvider.otherwise({ redirectTo: '/list'});
  }).

  factory('Project', function(parse) {
    return parse.forClassName('project');
  });



function ProjectListCntl($scope, Project) {
  $scope.projects = Project.query();
}



function ProjectCreateCntl($scope, $location, Project) {
  $scope.project = {name: '', site: '', description: ''};

  $scope.save = function() {
    Project.create($scope.project).then(function(project) {
      $location.path('/edit/' + project.objectId);
    });
  }
}



function ProjectEditCntl($scope, $location, $routeParams, Project) {
  var self = this;

  Project.get($routeParams.projectId).then(function(project) {
    self.project = project;
    $scope.project = angular.copy(self.project);
  });

  $scope.isClean = function() {
    return angular.equals(self.project, $scope.project);
  }

  $scope.destroy = function() {
    self.project.destroy().then(function() {
      $location.path('/list');
    });
  };

  $scope.save = function() {
    self.project.save($scope.project).then(self.cancel);
  };
}

// This is a module for http://parse.com data persistence
angular.module('parse', []).
  service('parse', ParseFactory);

function ParseFactory($http) {
  var self = this,
      config = {
        headers: {
          'X-Parse-Application-Id': 'iNMdOD7ijDce9udhcDoinc6vNaqY2olmtI4PMjxF',
          'X-Parse-REST-API-Key': 'xLtbY0V0Bhcy6XYLv6zNug0SxZqJWPnCRwm7kxPb',
          'X-Requested-With': undefined
        }
      };

  self.forClassName = function(className) {
    var Class = function(data) {
          angular.extend(this, data);
...