0

I am working on a Backbone-based webapp, which renders a clickable list of projects from a web service. When clicked, a form is populated with the attributes of that project. I am using Underscore templating to populate the attributes into an HTML page. Each project's attributes come from the same web service, with the project ID as an extra parameter to the URL root. I am getting the ID from the clicked element using the data-id property as described here, and creating the url for the model with a function that appends the root with this value.

This all works if I begin on the project list page, but if I refresh the specific project page with the appended URL (webservice/project_id), I receive a 'bad request' error, because the project ID part of the URL is not defined in the model. I understand why this is happening, but I am not sure how to fix this, or if I should approach the dynamic URL creation another way?

Here is the relevant code for the model:

 var ThisProject = Backbone.Model.extend({

      initialize: function() {

       ...
       },
       url: function(){
        thisProjURL = 'http://XX.XXX.XX/api/projects/' + thisProjID;
        return thisProjURL;

      }, .... 

and here is the view, which contains the list of clickable projects:

  var ListProjectView = Backbone.View.extend({
    events: {
     'click a': 'getId'
    },
    initialize: function() {
      this.render();
    },
    render: function() {
      var template = _.template(myprojecttpl);
      this.$el.html(template({collection: this.collection.toJSON()}));
    },

    getId: function(e){
       thisProjID = $(e.currentTarget).data("id");
    },

  });

This is the relevant line in the HTML file with the Underscore variable:

<% _.each(collection, function(model) { %>

<li><a href="#/thisproject-detail/<%= model.Pid %>" data-id="<%= model.Pid %>"><%= model.PjctName %></a></li>
<% }); %>

Below is the routing code:

  var AppRouter = Backbone.Router.extend({
    routes: {
      "" : "index", // this is where the list of projects is displayed
      "login": "login",
      "logout": "logout",
      "project-detail": "projectDetail",
      "thisproject-detail/:Pid": "thisProjectDetail", // this is the specific project
      "project-search": "projectSearch",
      "treatment-search": "treatmentSearch"
    }
  });
  // Initiate the router
  var app_router = new AppRouter;

  app_router.on('route:index', function() {

    var _projectCollection = new ProjectCollection();

    _projectCollection.fetch(
      { success : onDataHandler, error: onErrorHandler }
      ).then(function(response){
      var _ListProjectView = new ListProjectView({ collection: _projectCollection ,
        el: $("#myprojects")
      });
    });
  });

  app_router.on('route:thisProjectDetail', function(e) {

    var thisProjectData = new ThisProject();

          thisProjectData.fetch(
            { success : onThisDataHandler, error: onThisErrorHandler }
            ).then(function(response){
               var _ThisProjectDetailView = new ThisProjectDetailView({model: thisProjectData,
                el: $("#myprojects")
              });
        });
  });
Community
  • 1
  • 1
JasonBK
  • 539
  • 3
  • 12
  • 37

1 Answers1

0

I did find this solution..it seems to work but it's a bit hacky. I'd still be interested in other cleaner solutions:

(thisProjID is a global variable)

In my router for ThisProject model / thisProjectDetail view:

just add a check if thisProjID has no value; if so, get from URL:

  app_router.on('route:thisProjectDetail', function(e) {
    console.log("routed to this project");

    //new //
    if (thisProjID == "") { 
      var curURL = window.location.href;
      console.log(curURL);
      var projNum = (curURL.substr(curURL.lastIndexOf('/') + 1));
      thisProjID = projNum;

    }
    /////

    var thisProjectData = new ThisProject();

          thisProjectData.fetch(
            { success : onThisDataHandler, error: onThisErrorHandler }
            ).then(function(response){
               var _ThisProjectDetailView = new ThisProjectDetailView({model: thisProjectData,
                el: $("#myprojects")
              });

        console.log(thisProjectData);
        });
  });
JasonBK
  • 539
  • 3
  • 12
  • 37