Altinet
  • Home
  • Blog
  • Contact





RavenDB, Breeze, SPA and all that nice fluff stuff.

On 20 Aug, 2013
Uncategorized
By : Bruno Samardzic
No Comments
Views : 7876

Source RavenDbBreeze sample

I started taking much more interest in SPA development, and combination from the title has been gaining a lot of popularity lately, so i decided to give it a go. There are a few critical questions that i needed answered and since there are rather new technologies, the information is quite scattered.
I looked at a bunch of technologies, stacks, trying to get a hold of the best solution. Eventually i decided on doing some forking on the NoDB sample project from Breezejs and see if i can bend it to my will. So here is my WTFAQ while i was delving deep into the problem. And there’s gonna be a nice source code at the end of all this:).

So which nuget package should i get for quick and easy development?
Just one, and that’s RavenDB.Embedded. That should probably get you started.

What about starting framework, which one to choose?
Well, i would definitely go with Hot towel, it’s beautifully set up. But some other projects and templates i recommend are Twitter Bootstrap MVC 4 nuget (for authentication and templates) and NoDB sample from breeze site. Also, have a look at Edmunds sample for a 3rd party rest consumption with breeze.

So what are some of the gotchas?
Well, so far, i ran into one particularly annoying problem, and it concerns routing. It’s problematic if you’d like to add an outside link through mapNav function in durandal (which probably isn’t even meant for that). Trouble is, the routing on IE and Chrome behave differently (so the link will work on IE but not on Chrome). Also be prepared to learn alot about binding, modules etc. if you haven’t already. But ultimately, it’s a pretty sane solution for a Javascript:).

Is Breeze suited for storing documents, i.e. complex structures and using with NoSql and RavenDB?
The short answer is yes, and what’s even better, from what i’ve seen from breeze it’s a surprisnigly open, versatile and convenient framework for data manipulation. It really is extremely nice to work with, especially for seasoned silverlight veteran:). Now there are some stuff that need to be hand coded, but i think that it’s only a matter of time until a proper metadata provider is made for it. Other than that, i think i found my favourite solution for data manipulation on client side.

I have problems with ComplexType arrays, how do you set that up?
It’s a bit tricky for a beginner, but it’s mostly because of the lack of documentation. But once you set it all up it’s pretty straightforward. Have a look at the rearranged TodoItem, especially files todo.model.js and todo.datacontext.js.  TodoItem is now a complexType, which gets stored  in a TodoList document.

I also added a SaveChanges button, and to have it work properly you will have to comment out line 15 in todo.datacontext.js (//configureManagerToSaveModifiedItemImmediately();)

How about some code?
So let’s go over a few use cases. I reworked the NoDB sample from breeze website to use RavenDB and Complextype for Todos. Firstly, the metadata setup, i’ll show an excerpt  (todo.model.js)


function addTodoItemType(store) {
 store.addEntityType({
 shortName: "TodoItem",
 namespace: "NoDb.Models",
 isComplexType: true,
 dataProperties: {
 id: { dataType: DataType.String, isNullable: false },
 title: { dataType: DataType.String, maxLength: 30, isNullable: false,
 validators: [ Validator.required(), Validator.maxLength( {maxLength: 30})] // Add client-side validation to 'title'
 },
 isDone: { dataType: DataType.Boolean, isNullable: false },
 todoListId: { dataType: DataType.Int32, isNullable: false },

 }
 });

 function addTodoListType(store) {
 store.addEntityType({
 shortName: "TodoList",
 namespace: "NoDb.Models",
 autoGeneratedKeyType: AutoGeneratedKeyType.Identity,
 dataProperties: {
 id: { dataType: DataType.String, isNullable: false, isPartOfKey: true },
 title: { dataType: DataType.String, maxLength: 30, isNullable: false },
 todos: { dataType: DataType.ComplexType, complexTypeName:"TodoItem:#NoDb.Models", isScalar: false}
 },
 });

The important bits are the property isComplexType on TodoItem and the definition of todos property on TodoList. todos is defined as an array of TodoItems (isScalar:false and complexTypeName).
The next example will show how we add a new item to TodoList (todo.model.js)

        TodoList.prototype.addTodo = function () {
            if (this.newTodoTitle()) {
                var todoItem = datacontext.createTodoItem(
                {
                    title: this.newTodoTitle(),
                    id: DataType.Guid.getNext()
                });
                
                this.todos.push(todoItem);
                this.newTodoTitle("");
            }
        };

I decided to keep the id property for items, so i’m setting it up to guid. Additionally, i changed type of id across the board from int to string (much friendlier for Raven). There is a method createTodoItem which is defined in todo.datacontext.js and this is the way you create complexobjects:

    function createTodoItem(initialValues) {
        return manager.metadataStore.getEntityType("TodoItem").createInstance(initialValues);
    }

So instead of using new keyword, this way we get a nice observable object ready for databinding.

On the server-side i integrated TodoContext with RavenDb, it’s pretty standard affair. Note that while modifiying TodoItem, i am actually sending a whole list over the wire, which I find convenient, the list can be completely overwritten.
The code is attached to this post, so i think it will speak for itself a lot. If you have any trouble, leave a comment.
Cheers!



Previous Post Next Post 

About The Author

Bruno Samardzic


Number of Posts : 45
All Posts by : Bruno Samardzic

Leave a Comment

Click here to cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>





Recent Posts

  • Angular vs React: round 2
  • Why programming is hard
  • Orchard Workflows, undocumented gem
  • The React Redux
  • React.js invoicing CRUD application, part 2: Description

Recent Comments

  • Angshuman on Animation for starred grid rows and columns using xaml
  • Advanced Excel Training in Lucknow on Angular vs React: round 2
  • Reginald Sophomore on My example of Angularjs directive
  • Slobodan on Angular and Breeze – story so far.
  • Bruno Samardzic on Reaction to Ember-forged Durandal Angularly Knocking out my Backbone, or my JS MVC framework research conclusion.

Contact

Altinet d.o.o.

OIB: 97429091194

Čulinečka cesta 146, Zagreb

Tel: +385 (1) 2946 819

Mob: +385 (98) 210 756

IBAN: HR4323400091110406470

Latest tweets