2

I have a SPA site that I'm working on, I have a requirement that you can have subroutes for a page view model. Im currently using this 'pattern' for the site

MyApp.FooViewModel = MyApp.define({
    meta: {
        query: MyApp.Core.Contracts.Queries.FooQuery,
        title: "Foo"
    },
    init: function (queryResult) {

    },
    prototype: {               
    }
});

In the master view model I have a route table

this.navigation(new MyApp.RoutesViewModel({
    Home: {
        model: MyApp.HomeViewModel,
        route: String.empty
    },
    Foo: {
        model: MyApp.FooViewModel
    }
}));

The meta object defines which query should populate the top level view model when its invoked through sammyjs, this is all fine but it does not support sub routing

My plan is to change the meta object so that it can (optional offcourse) look like this

meta: {
    query: MyApp.Core.Contracts.Queries.FooQuery,
    title: "Foo",
    route: {
        barId: MyApp.BarViewModel
    }
}

When sammyjs detects a barId in the query string the Barmodel will be executed and populated through its own meta object.

Is this a good design?

edit: Hmm, just noticed that above design is not always enough, the parent view model might need to do some processing when the subRoute triggers, so I added a object to the definition sent into MyApp.define like

meta: {
    query: MyApp.Core.Contracts.Queries.FooQuery,
    title: "Foo",
    route: {
        barId: MyApp.BarViewModel
    }
},
onRoute: {
   barId: function(barViewModel) {
      //act on bar route
   }
}
  • I'm sorry but it's hard to resist “I have a SPA site”. – David Sergey Oct 25 '13 at 9:45
1

You don't need to role your own, Angular combined with ui-router is a great SPA framework for that sort of thing.

$stateProvider
  .state('home', {
      url: "/",
      templateUrl:'/home.html'
  })
  .state('foo', {
      url: "/foo",
      templateUrl:'/foo.html',
      resolve:{
         bar:  function(){
            return {'value': 'baz'};
         }
      },
      controller: ['$scope', 'bar', function($scope, bar) {
        $scope.bar = bar;  
      }]
  })
  .state('foo.bar', { //sub routing
      url: "/bar",  //actual /foo/bar
      templateUrl:'/bar.html',
      resolve:{
         baz:  function(){
            return {'value': 'buzz'};
         }
      },
      controller: ['$scope', 'baz', function($scope, baz) {
        //$scope.bar still = bar;  
        $scope.baz = baz;  
      }]
  })

;

It already allows great separation of concerns and has built-in dependency injection.

See this plunkr, for an example:

http://plnkr.co/edit/1mXGdrl8612Vyyo0WrUF?p=preview

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.