Feature: List repositories

Let's build the client for our feature List repositories. Each item in the list consists of a repository name, a short description, and a checkbox; which allows us to add or remove the repository from the project.

What follows is an HTML template ./templates/repositories.hbs for a repository item:

<li>
  <label class="checkbox inline">
  <input id="{{id}}" type="checkbox" {{enabled}} value="{{name}}"><h4 class="media-heading repoItem">{{name}}</h4>
  <small>{{description}}</small>
  </label>
</li>

Let's add a Repository model. We add a function Repository that extends the Backbone Model type and add a hash of default values for the four properties in our model. The enabled property signifies that a repository is included in the selected project.

Vision.Repository = Backbone.Model.extend({
    defaults: {
          id : ""
        , name: ""
        , description: ""
        , enabled: ""
    }
});

Let's implement a collection for our Repository model. We start by defining a function RepositoryList, which extends the Backbone Collection type. We add the projectId of the selected project, and set the model type as Vision.Repository. We then add a url method and use the web API route /project/:id/repos to get a list of repositories for a project.

The initialize method is called when the collection is instantiated; from here, we assign the selected projectId. The parse method is called when a fetch is performed and will parse the response; here we assign our MongoDB _id to the response.id.

Vision.RepositoryList = Backbone.Collection.extend({
    projectId: '',
    model: Vision.Repository,

    url : function() {
      return '/project/' + this.projectId + '/repos';
    },

    initialize: function(items, item) {
        this.projectId = item.projectId;
    },

    parse: function( response ) {
        response.id = response._id;
        return response;
    }
});

We now implement a view for a single repository. We add a function, RepositoryView, that extends the Backbone View type and add a tagName and assign li to it. This tag will be wrapped around our RepositoryView function; our DOM element is a ul tag. We include a viewTemplate function and assign our precompiled handlebars template templates/repositories.hbs to it. The render method renders the view; we pass the repository model to our viewTemplate function, which is then added via $el to our DOM element, and we return the view.

Vision.RepositoryView = Backbone.View.extend({
    tagName: "li",
    viewTemplate: visiontemplates["templates/repositories.hbs"],

    render: function () {
        this.$el.html(this.viewTemplate(this.model.toJSON()));
        return this;
    }
});

Let's implement a view for our RepositoryList called RepositoryListView. We start by defining a function, RepositoryListView, that extends the Backbone View type and adds a Repositories array for our repository list. We add an initialize method; if projectId is empty we return. A valid projectId results in rendering the view; first, we clear the DOM element, and we then assign a new RepositoryList function to the views collection. We initialize the list with our Repositories array and our projectId, we then call fetch in our collection, and then we call render for a successful fetch.

The render method uses underscore to loop through the repository collection called collection.models, calling add(item) for each project. We include an add method that instantiates a RepositoryView function, passing to it a repository model. We then append a rendered RepositoryView to our DOM element via $el and return the view.

Vision.RepositoryListView = Backbone.View.extend({
    Repositories: [],

    initialize: function (args) {
      if (!args.projectId) return;
      var me = this;
      this.$el.html(''),
      this.collection = new Vision.RepositoryList(this.Repositories, {
          projectId : args.projectId
        });
        this.collection.fetch({success: function(){
          me.render();
        }});
    },

    render: function () {
      _.each(this.collection.models, function (item) {
        this.add(item);
      }, this);
    },

    add: function (item) {
      var repositoryView = new Vision.RepositoryView({
        model: item
      });

      this.$el.append(repositoryView.render(this.editMode).el);
      return repositoryView;
    }
});

Let's make a few changes to our ProjectView and add a click event when selecting a project. We start by defining an events hash with a single event called click a, that calls the repository method. The repository method grabs projectId from our model and then calls the trigger method on event_aggregator for the event repository:join, passing projectId. We will listen to this event on ProjectListView.

    events: {
      "click a" : "repository"
    },

    repository: function() {
      var data = { projectId: this.model.toJSON()._id }
      this.event_aggregator.trigger('repository:join', data);
    },

Let's hook up the other side of the previous event and add an event binder to ProjectListView. We add an event_aggregator.bind statement to our initialize method, binding the event repository:join to the repository method. The repository method triggers a join event on the router.

    initialize: function () {
      this.event_aggregator.on('repository:join', this.repository, this);
        this.collection = new Vision.ProjectList(this.Projects);
        this.render();
    },

    repository: function(args){
      this.trigger('join', args);
    },

Let's complete the picture and change router to listen to the join event. We add a repositoryListView function to the router and add a listenTo event to the initialize method that calls the join method. The join method calls repository, which instantiates the RepositoryListView function, passing projectId.

repositoryListView:'',

initialize : function(){
  this.project();
  this.listenTo(this.projectListView , 'join', this.join);
},

join : function(args){
  this.repository(args);
},

repository : function(args){
  this.repositoryListView =new Vision.RepositoryListView({ el: 'ul#repository-list', projectId: args.projectId });
},

Now, when you click on a project item's name in ProjectView, RepositoryListView is displayed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.223.123