[{"data":1,"prerenderedAt":6095},["ShallowReactive",2],{"search-index-blog":3,"blog-\u002Fblog\u002Fbackbone-patterns":917,"surround-\u002Fblog\u002Fbackbone-patterns":6090},[4,11,19,24,30,35,41,46,52,57,62,67,72,78,84,90,95,101,107,113,118,125,130,135,141,146,151,156,163,168,174,179,185,190,195,200,205,210,215,221,226,231,236,241,246,251,256,261,266,272,277,282,287,293,298,304,309,314,319,325,330,335,340,345,351,356,363,368,373,378,384,389,394,399,405,410,415,420,426,432,437,443,448,454,459,464,469,474,480,485,490,495,500,505,510,515,521,526,531,537,542,547,552,557,562,567,573,579,584,589,594,599,604,609,614,620,625,630,635,640,645,651,656,661,666,671,676,682,687,692,697,702,707,712,719,724,729,734,739,745,750,755,760,765,770,775,780,786,791,797,802,808,813,818,823,829,834,839,844,849,854,860,865,871,876,881,886,891,896,901,906,912],{"title":5,"path":6,"description":7,"tags":8},"ADOBE ILLUSTRATOR SHORTCUTS","\u002Fblog\u002Fadobe-illustrator-shortcuts","Here are 26 Adobe Illustrator shortcuts that can help you to speed up productivity. I use most of them (in fact, I can’t work without them). Most of shortcuts listed in this article aren’t documented in the software, so keep reading and you’re sure to find at least one new trick to put up your sleeve. Enjoy!",[9,10],"design","illustrator",{"title":12,"path":13,"description":14,"tags":15},"ANGULAR CONTROLLERS SHARE STATE","\u002Fblog\u002Fangular-controllers-share-state","When your Angular.js application expands to a state that you no longer find it easy to understand, it's time you used dependency injection and modularise your application into units of interrelated modules.",[16,17,18],"development","javascript","angular.js",{"title":20,"path":21,"description":22,"tags":23},"ANGULAR TRANSLATE","\u002Fblog\u002Fangular-translate","Angular Translate is an AngularJS module called angular-translate which makes i18n and l10n easier with your Angular application. The acronym i18n stands for internationalization, and l10n for localization.",[16,17,18],{"title":25,"path":26,"description":27,"tags":28},"ANIMATION SPEED IN JAVASCRIPT AND CSS","\u002Fblog\u002Fanimation-speed-in-javascript-and-css","In this article, we go through how JavaScript-based DOM animation libraries, such as Velocity.js and GSAP, are more efficient than jQuery and CSS-based animation libraries. We will discuss how those libraries work, where to use them and what other alternatives are out there for animation.",[16,17,29],"css",{"title":31,"path":32,"description":33,"tags":34},"ARRAY COMPREHENSIONS","\u002Fblog\u002Farray-comprehensions","Array comprehension is creating a list B based on another list A, where each entry of B is the result of a custom operation performed on the items of list A.",[16,17],{"title":36,"path":37,"description":38,"tags":39},"ASYNCHRONOUS JAVASCRIPT WITH ASYNC\u002FAWAIT","\u002Fblog\u002Fasynchronous-javascript-asyncawait","'Promises are great but the its nested syntax can get easily complex and hard to follow.",[16,17,40],"react",{"title":42,"path":43,"description":44,"tags":45},"BABEL & WEBPACK","\u002Fblog\u002Fbabel-webpack","Babel has been one of the big newcomers of JavaScript community in 2015. It allows us to use features from the future of JavaScript. It will transform your futuristic code into a format, browsers understand. You can even use it to develop your own language features. Babel’s built-in JSX support will come in handy here.",[16,17],{"title":47,"path":48,"description":49,"tags":50},"BACKBONE CUSTOMIZING COLLECTIONS","\u002Fblog\u002Fbackbone-customizing-collections","Backbone collections are an ordered set of models, which only use one type of model. Customizing these collections can help your Backbone application to leverage data the way you want.",[16,17,51],"backbone.js",{"title":53,"path":54,"description":55,"tags":56},"BACKBONE – MODELS","\u002Fblog\u002Fbackbone-models","Models are the heart of any JavaScript MVC application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.",[16,17,51],{"title":58,"path":59,"description":60,"tags":61},"BACKBONE PATTERNS","\u002Fblog\u002Fbackbone-patterns","In this article, we’ll discuss different patterns that you can use with popular open-source JavaScript MV* framework, Backbone.js.  Developers run into problems when they first use Backbone.js as it provides structure to the application leaving the developer to make decisions on design petterns.",[16,17,51],{"title":63,"path":64,"description":65,"tags":66},"BACKBONE- ROUTERS","\u002Fblog\u002Fbackbone-routers","In the traditional MVC sense Routers don’t necessarily fit the semantics. Though a Backbone \"router\" is still very useful for any application\u002Ffeature that needs URL routing\u002Fhistory capabilities. Backbone routers are used for routing your applications URL’s when using hash tags(#).",[16,17,51],{"title":68,"path":69,"description":70,"tags":71},"BEM","\u002Fblog\u002Fbem","BEM stands for Block, Element, Modifier. BEM is a stricter standard for naming CSS classes for larger projects, where standards need to be enforced. BEM helps scale your project, and add meaning to your CSS. Therefore it is valuable to understand this convention.",[16,29],{"title":73,"path":74,"description":75,"tags":76},"BENEFITS OF AUTOMATED DEPLOYMENT","\u002Fblog\u002Fbenefits-of-automated-deployment","When deploying software manually, the tendancy is to deploy once a month or perhaps once every two or three months. Deployment doesn’t stop for production only, there are test, staging and production as well.",[16,77],"deployment",{"title":79,"path":80,"description":81,"tags":82},"BROWSERSYNC & GULP","\u002Fblog\u002Fbrowsersync-gulp","BrowserSync & Gulp are a two very useful combination when it comes to developing applications efficiently, without having to refresh the web page every time you make a change. Let’s look at what BrowserSync & Gulp are, and how to install and use them.",[16,17,83],"gulp",{"title":85,"path":86,"description":87,"tags":88},"CHROMATIC ABERRATION","\u002Fblog\u002Fchromatic-aberration","In optical lenses, chromatic aberration (also known as achromatism or chromatic distortion) is a type of  distortion in which there is a failure of a lens to focus all colors to the same convergence point.",[89],"photography",{"title":91,"path":92,"description":93,"tags":94},"CHROME DEVTOOLS FOR WEB APP DEVELOPERS","\u002Fblog\u002Fchrome-devtools-web-app-developers","The Chrome DevTools (Developer Tools), are a set web authoring and debugging tools built into Google Chrome. The DevTools provide web developers deep access into the internals of the browser and their web application. ",[16,17],{"title":96,"path":97,"description":98,"tags":99},"COFFEESCRIPT INTRODUCTION","\u002Fblog\u002Fcoffeescript-introduction","CoffeeScript is a language that makes JavaScript easier to write and read. It simplifies JavaScript, making it readable and understandable, as well easier to maintain. CoffeeScript compiles into JavaScript",[16,17,100],"coffeescript",{"title":102,"path":103,"description":104,"tags":105},"COFFEESCRIPT – JQUERY","\u002Fblog\u002Fcoffeescript-jquery","Writing jQuery in CoffeeScript, further simplifies the syntax. The jQuery(function($)) can be written as jQuery($) -> or simply $ ->.",[16,17,106,100],"jquery",{"title":108,"path":109,"description":110,"tags":111},"CONTENT AWARE SCALING IN PHOTOSHOP","\u002Fblog\u002Fcontent-aware-scaling-in-photoshop","In Photoshop CS6, content-aware scaling (also known as seam carving) is a cool image-sizing feature.",[9,112],"photoshop",{"title":114,"path":115,"description":116,"tags":117},"CREATE FAVICONS IN PHOTOSHOP","\u002Fblog\u002Fcreate-favicons-in-photoshop","'Having a favicon for your site helps users to find your web site on a bookmarks bar, or among open tabs.",[9,112],{"title":119,"path":120,"description":121,"tags":122},"CREATE A RAILS 5 API APPLICATION","\u002Fblog\u002Fcreate-rails-5-api-application","'Rails 5 ships a new gem rails-api which makes building API only rails apps a breeze.",[16,123,124],"rails","ruby",{"title":126,"path":127,"description":128,"tags":129},"CSS – CLEARING FLOATS","\u002Fblog\u002Fcss-clearing-floats","A common problem with float-based layouts is that the floats' container doesn't want to stretch up to accommodate the floats. If you want to add, say, a border around all floats (ie. a border around the container) you'll have to command the browsers somehow to stretch up the container all the way.",[16,17],{"title":131,"path":132,"description":133,"tags":134},"CSS INTRODUCTION","\u002Fblog\u002Fcss-introduction","Cascading Style Sheets (CSS) is a style sheet language used for describing the look and formatting of a document written in a markup language, most often used to change the style of web pages written in HTML. CSS is designed primarily to enable the separation of document content from document presentation, including elements such as the layout, colors, and fonts.",[16,29],{"title":136,"path":137,"description":138,"tags":139},"CSS MODULES","\u002Fblog\u002Fcss-modules","A CSS Module is a CSS file in which all class names and animation names are scoped locally by default, eleminating the problems with global nature of the CSS namespace.",[16,17,29,140],"react.js",{"title":142,"path":143,"description":144,"tags":145},"CSS3 MEDIA QUERIES","\u002Fblog\u002Fcss3-media-queries","When you are designing your responisve layout for mobile devices, CSS3 media queries are an essential component on your stylesheets. Let’s discuss how they work and what min-with and max-with work together.",[16,29],{"title":147,"path":148,"description":149,"tags":150},"DEFERRED AND PROMISE IN JQUERY","\u002Fblog\u002Fdeferred-and-promise-in-jquery","Deferred and promise are part of jQuery since version 1.5 and they help in handling asynchronous functions like Ajax.",[16,17,106],{"title":152,"path":153,"description":154,"tags":155},"DEPLOYING ASP.NET MVC APPLICATIONS","\u002Fblog\u002Fdeploying-aspnet-mvc-applications","In a continuous integration environment, deploying ASP.NET MVC applications are done by a click of a button, triggered by a check-in, and then  many moving parts of the integration service will take care of distributing the artifacts to the relevant  servers. But here we are discussing about how to get your ASP.NET code to be tested on a local IIS server environment. So let’s start with dependancies, and what needs to be included with the deployment.",[16,17],{"title":157,"path":158,"description":159,"tags":160},"DEVELOP MOBILE APPS WITH PHONEGAP","\u002Fblog\u002Fdevelop-mobile-apps-phonegap","PhoneGap is a web-based mobile development framework based on opened source Cordova project, which allows you to create app store ready mobile applications. PhoneGap allows you to use web technologies such as HTML, CSS and JavaScript for cross platform development. It was created by Nitobi in 2009. In 2011, Nitobi was bought by Adobe, and PhoneGap was donated to Apache Foundation, and PhoneGap was renamed to Cordova.",[16,161,17,162],"mobile","phonegap",{"title":164,"path":165,"description":166,"tags":167},"DODGE BURN AND SPONGE TOOLS IN PHOTOSHOP CS6","\u002Fblog\u002Fdodge-burn-and-sponge-tools-in-photoshop-cs6","The Dodge, Burn, and Sponge tools in Photoshop CS 6 can be used to correct the lighting of an image. Let’s look at each of these tools and what they are useful for.",[9,89,112],{"title":169,"path":170,"description":171,"tags":172},"EMBER & HANDLEBARS","\u002Fblog\u002Fember-handlebars","Before getting into handlebars, let's look at how routing works in Ember.js. Router is solely responsible for all URLs in Ember.",[16,17,173],"ember.js",{"title":175,"path":176,"description":177,"tags":178},"EMBER – RESOURCE ROUTES","\u002Fblog\u002Fember-resource-routes","The difference between resource() and route() in Ember.js is that you should use this.resource for URLs that represent a noun, and this.route for URLs that represent adjectives or verbs modifying those nouns.",[16,17,173],{"title":180,"path":181,"description":182,"tags":183},"ENTITY FRAMEWORK CODE FIRST","\u002Fblog\u002Fentity-framework-code-first","Entity Framework introduced Code First approach from Entity Framework 4.1. This tutorial covers all the features of Entity Framework Code-First. We will start with the basics of code-first and then we will see how we can configure one-to-one, one-to-many and many-to-many relationship with DataAnnotation as well as Fluent API.",[16,184],"csharp",{"title":186,"path":187,"description":188,"tags":189},"ES2020 New Features","\u002Fblog\u002Fes2020-new-features","Since ES2015, updates from the TC39 committee are released annually. Their latest release ES2020 comes with many new features.",[16,17],{"title":191,"path":192,"description":193,"tags":194},"ES6 ADVANCED FEATURES","\u002Fblog\u002Fes6-advanced-features","We have learned about the new features ES6 brings us in ES6 New Features article. In this post, we will go through the advanced features of ES6 and how we can implement them.",[16,17],{"title":196,"path":197,"description":198,"tags":199},"ES6 ARROW FUNCTIONS","\u002Fblog\u002Fes6-arrow-functions","Arrow functionss are a function shorthand using the => syntax (fat arrow). They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both expression and statement bodies. Unlike functions, arrows share the same lexical this as their surrounding code.",[16,17],{"title":201,"path":202,"description":203,"tags":204},"ES6 CLASSES","\u002Fblog\u002Fes6-classes","JavaScript classes are simply syntactic sugar over existing JavaScript prototype chain. But classes give you a cleaner way to organise your code, and make it slightly easier for the beginner or people who are familiar with class oriented languages to read JS and understand.",[16,17],{"title":206,"path":207,"description":208,"tags":209},"ES6 DEFAULT, REST & SPREAD","\u002Fblog\u002Fes6-default-rest-spread","Many programming languages support the concept of a default argument for a function parameter so that the caller does not always need to specify the argument value. Unfortunately, ES5 does not have a default argument support in its syntax. ES6 functions have come a long way by taking aboard the years of complaints and improving parameter handling that is less error-prone and more powerful.",[16,17],{"title":211,"path":212,"description":213,"tags":214},"ES6 DESTRUCTURING","\u002Fblog\u002Fes6-destructuring","The destructuring assignment syntax is a JavaScript expression in ES6 that makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.",[16,17],{"title":216,"path":217,"description":218,"tags":219},"ES6 GENERATORS","\u002Fblog\u002Fes6-generators","ES6 generators are functions that can be paused or resumed, and work cooperatively in a multitasking applications.",[16,17,220],"es6",{"title":222,"path":223,"description":224,"tags":225},"ES6 ITERATORS & FOR..OF","\u002Fblog\u002Fes6-iterators-for-of","To loop over an array or a collection JavaScript has been traditionally using for loops. ES5 introduced the for ..each loop. But ES6 introduces a little shorter version, a new interface for iteration called Iterable.",[16,17],{"title":227,"path":228,"description":229,"tags":230},"ES6 LET & CONST","\u002Fblog\u002Fes6-let-const","If you are familiar with JavaScript, you have probably known the term scope. If you are familiar with other languages, you would know that a scope of a variable is to the nearest block – block scope. But JavaScript is different. A variable created with var will be scoped to the nearest parent function.",[16,17],{"title":232,"path":233,"description":234,"tags":235},"ES6 MODULES","\u002Fblog\u002Fes6-modules","A module is a self-contained unit of code, which is usually stored in a file. In ES6, modules get language-level support for component definition. Modules export values, which can then be imported by other modules.",[16,17],{"title":237,"path":238,"description":239,"tags":240},"ES6 NEW FEATURES","\u002Fblog\u002Fes6-new-features","Arrows are a function shorthand using the => syntax (‘fat arrow’). They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both expression and statement bodies. Unlike functions, arrows share the same lexical this as their surrounding code.",[16,17],{"title":242,"path":243,"description":244,"tags":245},"WEB APPLICATION SECURITY","\u002Fblog\u002Fes6-parameter-handling","ES6 introduced improved parameter handling in JavaScript. Instead of the half array arguments object, these new improvements will significantly improve how we handle arguments and parameters.",[16,17,220],{"title":247,"path":248,"description":249,"tags":250},"ES6 RECURSION WITH FUNCTIONAL PROGRAMMING","\u002Fblog\u002Fes6-recursion-with-functional-programming","In this article, we are going to use ES6 recursion with functional programming to understand how we can implement list operations like map, reduce, filter and join.",[16,17,220],{"title":252,"path":253,"description":254,"tags":255},"ES6 SYMBOLS","\u002Fblog\u002Fes6-symbols","Symbols are a new primitive type in ES6. If you ask me, they’re an awful lot like strings. They are tokens that serve as unique IDs. They will help avoid name clashes between properties.",[16,17],{"title":257,"path":258,"description":259,"tags":260},"ES6 TEMPLATE STRINGS","\u002Fblog\u002Fes6-template-strings","Template strings in JavaScript consist of literal text, and placeholders where the runtime can evaluate an expression to inject data into the text.",[16,17],{"title":262,"path":263,"description":264,"tags":265},"ESLINT","\u002Fblog\u002Feslint","ESLint is a pattern identifying and reporting tool for JavaScript code. Somewhat it is similar to JSLint and JSHint with few differences.",[16,17],{"title":267,"path":268,"description":269,"tags":270},"EXT JS DEVELOPING RESPONSIVE APPLICATIONS","\u002Fblog\u002Fext-js-developing-responsive-applications","Creating responsive web applications have been made easier with the arrival of the new JavaScript Framework Ext JS 5. In this article let's look at how we can use responsiveConfig to implement this feature.",[16,17,271],"ext.js",{"title":273,"path":274,"description":275,"tags":276},"EXT.JS – INTRODUCTION","\u002Fblog\u002Fext-js-introduction","Ext JS is a product of Sencha. Ext JS is the industry’s most powerful desktop application development platform with unparalleled cross-browser compatibility, advanced MVC architecture, plugin-free charting, and modern UI widgets.",[16,17,271],{"title":278,"path":279,"description":280,"tags":281},"FETCH API","\u002Fblog\u002Ffetch-api","The Fetch API is a Promise-based standard for performing AJAX requests. It provides a fetch method which returns a Promise on the window object, which we can use to perform requests from remote resources.",[16,17],{"title":283,"path":284,"description":285,"tags":286},"FOCAL LENGTH AND F-STOP","\u002Fblog\u002Ffocal-length-f-stop","Very simply, focal-length is the distance from the lens to the film, when focused on a subject at infinity. In other words, focal length equals image distance for a far subject. To focus on something closer than infinity, the lens is moved farther away from the film or sensor. This is why most lenses get longer when you turn the focusing ring.",[89],{"title":288,"path":289,"description":290,"tags":291},"FOUNDATION 5 NEW FEATURES","\u002Fblog\u002Ffoundation-5-new-features","ZURB’s Foundation framework is a feature-rich, easy to implement,  light weight framework for designing responsive web applications. Designed with mobile-first approach in mind,  it comes packed with CSS3 media queries, The Grid, reusable HTML5 components and several jQuery plugins to aid interactivity.",[16,29,292],"sass",{"title":294,"path":295,"description":296,"tags":297},"FREE PHOTOSHOP PLUGINS","\u002Fblog\u002Ffree-photoshop-plugins","There are so many amazing free Photoshop plugins you can download for Photoshop CS6 and CC. There are plugins for photo effects, noise reduction, painting, abstract art, layouts, and more! Let’s have a look at few of the best.",[9,112],{"title":299,"path":300,"description":301,"tags":302},"FRONT END PERFORMANCE","\u002Fblog\u002Ffront-end-performance","Front end performance can be a great experience or a horrifying nightmare that could highly impact the end user experience, and lead to users leaving your website.",[16,303],"performance",{"title":305,"path":306,"description":307,"tags":308},"FUNCTIONAL JAVASCRIPT","\u002Fblog\u002Ffunctional-javascript","To understand Functional JavaScript and the quirks of JavaScript, we will have to look into the history of JavaScript and how it was created.",[16,17],{"title":310,"path":311,"description":312,"tags":313},"FUNCTIONAL PROGRAMMING","\u002Fblog\u002Ffunctional-programming","Abstract control flow and operations on data with functions in order to avoid side effects & reduce mutation of state",[16,17],{"title":315,"path":316,"description":317,"tags":318},"GIT – CLONING & BRANCHING","\u002Fblog\u002Fgit-cloning-branching","Imagine you are working in a team and one of your colleagues wants a copy of the your work, how do we start collaborating?",[16,17],{"title":320,"path":321,"description":322,"tags":323},"GIT INTRODUCTION","\u002Fblog\u002Fgit-introduction","Git is a distributed source control system, that is lighting fast and different from client-server systems. In this tutorial, we will learn how to get started with Git. By the end of this tutorial, you should be able to create a Git repository, record snapshots of your project for safekeeping, and view your project's history.",[16,324],"git",{"title":326,"path":327,"description":328,"tags":329},"GIT STAGING & REMOTES","\u002Fblog\u002Fgit-staging-remotes","Let’s say you are working on your local branch, made some changes and now not sure which files you have changed, how are you going to find your changes? You can find your changes by running the git diff command as below:",[16,324],{"title":331,"path":332,"description":333,"tags":334},"GIT STASH","\u002Fblog\u002Fgit-stash","Say you are halfway done with work on a branch, but an issue with 'master' needs fixing NOW. You're not quite ready to commit what you're working on, but need to make a quick fix to master. Fear not, just stash your current changes so you can switch to master quickly.",[16,324],{"title":336,"path":337,"description":338,"tags":339},"GOOGLE DRIVE – AUTHENTICATION","\u002Fblog\u002Fgoogle-drive-authentication","When you are developing an application interfacing Google Driver API, it's mandatory to consider how you are going to handle the authentication for your user. In this article, we are discussing how to implement Google Drive Authentication for your app via its API.",[16,17],{"title":341,"path":342,"description":343,"tags":344},"GOOGLE PICKER WITH DRIVE","\u002Fblog\u002Fgoogle-picker-with-drive","\"Google Drive is a file storage service that enables users to organize, backup, and",[16,17],{"title":346,"path":347,"description":348,"tags":349},"GRUNT WATCH & LIVERELOAD WITH JAVASCRIPT & SASS","\u002Fblog\u002Fgrunt-watch-livereload-with-javascript-sass","Grunt is a task runner that has a ton of plugins for doing things like compiling LESS\u002FSASS into CSS, concatenating JavaScript, minifying, etc. It also has a package for watching files (the same way CodeKit and Prepros does) and firing off certain tasks when they’re modified.",[16,17,350],"grunt",{"title":352,"path":353,"description":354,"tags":355},"HOW TO USE GRUNT","\u002Fblog\u002Fhow-to-use-grunt","In this article, we’ll look at how to use Grunt in your project to automate some of your repetitive tasks. We’ll look at what Grunt is, how to setup Grunt and then create a simple project with Grunt doing the heavy lifting of the some of the tasks.",[16,17,350],{"title":357,"path":358,"description":359,"tags":360},"HOW TO ADD A COVER TO AN EPUB, PDF OR A KINDLE MOBI BOOK","\u002Fblog\u002Fhow-to-add-a-cover-to-an-epub-pdf-or-a-kindle-mobi-book","EPUB, PDF and Kindle MOBI books converted from other formats or downloaded from torrent sites are sometimes cover-missing, which inevitably makes the whole eBook-reading journey less satisfactory",[361,362],"technology","tips",{"title":364,"path":365,"description":366,"tags":367},"How to lint staged Git files","\u002Fblog\u002Fhow-to-lint-staged-git-files","We use linting to automate code formatting issues, to fix syntax errors and coding style. For example, you may have forgotten a semi-colon during aor bug fix you may have accidentally left a console.log statement.",[16,17],{"title":369,"path":370,"description":371,"tags":372},"HOW TO MAKE AJAX CALLS IN JQUERY","\u002Fblog\u002Fhow-to-make-ajax-calls-in-jquery","There are more than one way to make AJAX calls in jQuery. In this tutorial, let’s compare these methods as well as inspect the AJAX calls with Firebug.",[16,17],{"title":374,"path":375,"description":376,"tags":377},"HOW TO USE TELEPHOTO LENSES","\u002Fblog\u002Fhow-to-use-telephoto-lenses","Telephoto lenses are useful for wildlife and landscape photography, given their ability to enlarge distant subjects, but they’re also great for giving your photo an artistic look.",[89],{"title":379,"path":380,"description":381,"tags":382},"HTML INTRODUCTION","\u002Fblog\u002Fhtml-introduction","The language of a webpage is HTML. HTML allows you to take a plain text document created in any simple text editor and organize it into lists, link to other webpages, including images, and more.",[16,383],"html",{"title":385,"path":386,"description":387,"tags":388},"HTML5 API – LOCAL STORAGE, GEOLOCATION & OFFLINE CACHE MANIFEST","\u002Fblog\u002Fhtml5-api-local-storage-geolocation-offline-cache-manifest","Local storage is more secure, and large amounts of data can be stored locally, without affecting website performance. Unlike cookies, the storage limit is far larger (at least 5MB) and information is never transferred to the server.",[16,17],{"title":390,"path":391,"description":392,"tags":393},"HTML5 ELEMENTS","\u002Fblog\u002Fhtml5-elements","HTML5 offers new elements for improving semantics of code as well as better document structure. These elements could now be used to replace traditional HTML code like \u003Cdiv id=”nav”> \u003Cdiv class=”header”> \u003Cdiv id=”footer”>",[16,383],{"title":395,"path":396,"description":397,"tags":398},"HTML5 INTRODUCTION","\u002Fblog\u002Fhtml5-introduction","HTML5 is the latest HTML standard. It walks hand in hand with CSS3, the latest CSS standard.",[16,17],{"title":400,"path":401,"description":402,"tags":403},"HTTP2: NEW FEATURES","\u002Fblog\u002Fhttp2-new-features","HTTP\u002F2 (originally named HTTP\u002F2.0) is the second major version of the HTTP network protocol used by the World Wide Web.",[16,404],"http2",{"title":406,"path":407,"description":408,"tags":409},"IMMUTABLE.JS","\u002Fblog\u002Fimmutable-js","Immutable.js is a library from Facebook which provides immutable data structures and utilities that we can introduce to our applications",[16,17],{"title":411,"path":412,"description":413,"tags":414},"Improve JavaScript Performance with Tree Shaking","\u002Fblog\u002Fimprove-javascript-performance-with-treeshaking","Tree shaking is the process used by bundlers like Webpack for dead-code elimination in JavaScript.",[16,17],{"title":416,"path":417,"description":418,"tags":419},"Improving JavaScript Performance for Web","\u002Fblog\u002Fimproving-javascript-performance-for-web","JavaScript optimisation is becoming increasingly necessary for improving application performance. Let’s look at some of the challenges associated with JavaScript and how to optimise performance.",[16,17,303],{"title":421,"path":422,"description":423,"tags":424},"Improving Next.js Performance","\u002Fblog\u002Fimproving-next-js-performance","Next.js is a zero-config React framework for building server-side and static web applications bundled with enhanced developer experience with features for products such as smart bundling, TypeScript support, route pre-fetching, hybrid static & server rendering, and more.",[16,17,425,303],"nextjs",{"title":427,"path":428,"description":429,"tags":430},"INDEXEDDB","\u002Fblog\u002Findexeddb","IndexedDB stands for Indexed Database, is a web standard for storing large amounts of client-side data in a structured manner. This low-level API is able to index data which enables performance rich search on data.",[16,17,431],"indexeddb",{"title":433,"path":434,"description":435,"tags":436},"INSTALL D-LINK DWA-125 WIRELESS DRIVER ON LINUX","\u002Fblog\u002Finstall-d-link-dwa-125-wireless-driver-on-linux","'If you have recently bought a D-Link Wireless Adapter (DWA-125) for your Linux machine and wondering how to get it working, this article might help you get started.",[361,362],{"title":438,"path":439,"description":440,"tags":441},"INSTALLING NODE.JS","\u002Fblog\u002Finstalling-node-js","In this article we are discussing how to get Node.js working on OSX along with npm, the package manager for node.",[16,17,442],"node.js",{"title":444,"path":445,"description":446,"tags":447},"INTEROPERABLE CSS","\u002Fblog\u002Finteroperable-css","Interoperable CSS or ICSS is a low-level file format that enables CSS Modules, designed for loader implementers (not for end users).",[16,29],{"title":449,"path":450,"description":451,"tags":452},"INTRODUCTION TO D3","\u002Fblog\u002Fintroduction-to-d3","D3 is a data visualization library written in JavaScript. It stands for Data-Driven Documents where Document stand for the DOM or the Docucment Object Model of a wweb page.",[16,17,453],"d3",{"title":455,"path":456,"description":457,"tags":458},"INTRODUCTION TO EMBER.JS","\u002Fblog\u002Fintroduction-to-ember-js","Ember.js is a JavaScript web application framework based on the MVC architectural pattern. It allows developers to create scalable single-page applications by incorporating common idioms and best practices into a framework that provides a rich object model, declarative two-way data binding, computed properties, automatically-updating templates powered by Handlebars.js, and a router for managing application state.",[16,17,173],{"title":460,"path":461,"description":462,"tags":463},"INTRODUCTION TO GULP","\u002Fblog\u002Fintroduction-to-gulp","Gulp is a JavaScript task runner. It’s an alternative to Grunt, which allowed you to define your tasks using JavaScript inside of a file called Gruntfile.js. In this tutorial, I’ll show you how to install Gulp and create a simple configuration file to get your feet wet with this great new task runner.",[16,17,83],{"title":465,"path":466,"description":467,"tags":468},"INTRODUCTION TO HAPI","\u002Fblog\u002Fintroduction-to-hapi","Created by Eran Hammer, hapi.js is an open source framework built on top of Node.js for building web applications and services by Wallmart. In this tutorial, we will go through the advantages of hapi and build a simple application using hapi as the server.",[16,17,442],{"title":470,"path":471,"description":472,"tags":473},"INTRODUCTION TO WEBPACK","\u002Fblog\u002Fintroduction-to-webpack","Webpack is a module bundler. Webpack takes modules with dependencies and generates static assets representing those modules.",[16,17,140],{"title":475,"path":476,"description":477,"tags":478},"ios-7-design-guidelines","\u002Fblog\u002Fios-7-design-guidelines","With the release of iOS 7 design guidelines, app designers and developers will have to adjust the language to match the new \"flat\" design of iOS. In addition to the grid system, the dimensions of icons and commonly used elements, typography and iconography has been updated by Apple in many ways.",[16,9,479],"ios",{"title":481,"path":482,"description":483,"tags":484},"ISO NOISE REDUCTION","\u002Fblog\u002Fiso-noise-reduction","Using great noise reduction is like upgrading your lens. Why do we pay 16x more for one 50mm lens vs. another?",[89],{"title":486,"path":487,"description":488,"tags":489},"ISOMORPHIC JAVASCRIPT","\u002Fblog\u002Fisomorphic-javascript","Isomorphic JavaScript means that we get to share the same code on the client and on the server. So basically, you are rendering your application markup on the server and piping it down as complete HTML to the browser.",[16,17],{"title":491,"path":492,"description":493,"tags":494},"ITCSS","\u002Fblog\u002Fitcss","ITCSS or Inverted Triangle CSS is a meta framework designed to address some common issues around CSS we encounter today. Introduced by Harry Roberts, it is a sane, scalable, managed architecture for CSS.",[16,29],{"title":496,"path":497,"description":498,"tags":499},"JAVASCRIPT ARRAYS","\u002Fblog\u002Fjavascript-arrays","This beginner-level article will discuss further about JavaScript arrays in detail. JavaScript arrays are used to store multiple values in a single variable. JavaScript has an built-in object for manipulating arrays called Array.",[16,17],{"title":501,"path":502,"description":503,"tags":504},"JAVASCRIPT & CLOSURES","\u002Fblog\u002Fjavascript-closures","A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain.",[16,17],{"title":506,"path":507,"description":508,"tags":509},"JAVASCRIPT CONSOLE","\u002Fblog\u002Fjavascript-console","'The JavaScript Console or the Console Object provides access to the browser’s debugging console.",[16,17],{"title":511,"path":512,"description":513,"tags":514},"JAVASCRIPT & CONSTRUCTOR","\u002Fblog\u002Fjavascript-constructor","ECMAScript is a object based language. An object has a built-in property named constructor.",[16,17],{"title":516,"path":517,"description":518,"tags":519},"JavaScript Design Patterns","\u002Fblog\u002Fjavascript-design-patterns","Design patterns are advanced object-oriented solutions to commonly occurring software problems.  Patterns are about reusable designs and interactions of objects.  Each pattern has a name and becomes part of a vocabulary when discussing complex design solutions.",[16,17,520],"patterns",{"title":522,"path":523,"description":524,"tags":525},"JAVASCRIPT HOISTING AND SCOPE","\u002Fblog\u002Fjavascript-hoisting-and-scope","Hoisting is JavaScript's default behaviour of moving all declarations to the top of the current scope (to the top of the current script or the current function). In different words, a variable can be used before it has been declared.",[16,17],{"title":527,"path":528,"description":529,"tags":530},"JAVASCRIPT & PROTOTYPE","\u002Fblog\u002Fjavascript-prototype","Prototype objects are just simple JavaScript objects and may have their own prototypes. If a prototype has a non-null reference to its prototype, and so on, this is called the prototype chain.",[16,17],{"title":532,"path":533,"description":534,"tags":535},"JELLY BEAN (ANDROID 4.1 SDK) NEW FEATURES","\u002Fblog\u002Fjelly-bean-android-4-1-sdk-new-features","In this article I would like to discuss the new features of Jelly Bean, what has changed from the previous releases, and more.",[361,536],"android",{"title":538,"path":539,"description":540,"tags":541},"JQUERY INTRODUCTION","\u002Fblog\u002Fjquery-introduction","JQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers.",[16,17,106],{"title":543,"path":544,"description":545,"tags":546},"JQUERY – HOW TO USE","\u002Fblog\u002Fjquery-use","In this article we’ll look at how we can use jquery to manipulate, traverse and select DOM elements at ease. Before we start we have to download jquery and load it in your HTML document",[16,17,106],{"title":548,"path":549,"description":550,"tags":551},"LEXICAL SCOPE","\u002Fblog\u002Flexical-scope","Lexical scope means that scope is defined by author-time decisions of where functions are declared. The lexing phase of compilation is essentially able to know where and how all identifiers are declared, and predict how they will be looked up during execution.",[16,17],{"title":553,"path":554,"description":555,"tags":556},"MAINTAINABLE JAVASCRIPT","\u002Fblog\u002Fmaintainable-javascript","If you are working on a project by your own, you might not worry about the structure, convention and organisation of your code given you fully understand how it works. But working in a team environment it is necessary to make sure that your team members understand your code, easily adaptable and extensible so the importance of maintainable javascript is inevitable.",[16,17],{"title":558,"path":559,"description":560,"tags":561},"MOBILE WEB INTRODUCTION","\u002Fblog\u002Fmobile-web-introduction","What is the mobile web? The mobile web refers to access to the world wide web, i.e. the use of browser-based Internet services, from a handheld mobile device, such as a smartphone or a feature phone, connected to a mobile network or other wireless network.",[16,29,161],{"title":563,"path":564,"description":565,"tags":566},"MODELS & EMBER DATA","\u002Fblog\u002Fmodels-ember-data","If you are thinking of consuming data in your Ember application, you can store them in fixtures. But what if you want to fetch data from a server?",[16,17,173],{"title":568,"path":569,"description":570,"tags":571},".NET FRAMEWORK Q&A","\u002Fblog\u002Fnet-framework-qna","In this article, we are discussing few common .NET frequently asked questions and answers.",[16,572],".net-framework",{"title":574,"path":575,"description":576,"tags":577},"NextJS Client-side, Server-side & Static Rendering","\u002Fblog\u002Fnextjs-client-side-server-side-and-static-rendering","The future of SEO and search ranking algorithms are now in heavy favour of static or server-side rendering. This means building static or server-side rendered apps instantly gain advantages in rankings.",[16,17,425,578],"ssr",{"title":580,"path":581,"description":582,"tags":583},"NODE JS SECURITY","\u002Fblog\u002Fnode-js-security","Node.js has gained momentum in the recent years but there are not many security guidelines available out there.",[16,17],{"title":585,"path":586,"description":587,"tags":588},"NODE.JS – EVENTS","\u002Fblog\u002Fnodejs-events","Many objects in Node emit events: a net.Server emits an event each time a peer connects to it, and fs.readStream emits an event when the file is opened. All objects which emit events are instances of events.EventEmitter.",[16,17,442],{"title":590,"path":591,"description":592,"tags":593},"NODEJS INSTALL WITH NVM","\u002Fblog\u002Fnodejs-install-with-nvm","Node Version Manager is a simple bash script to manage multiple active node.js versions. In this article, we are going to discuss about managing NodeJS install with NVM.",[16,17,442],{"title":595,"path":596,"description":597,"tags":598},"NODE.JS INTRODUCTION","\u002Fblog\u002Fnodejs-introduction","\"Node.js allows you to build scalable network",[16,17,442],{"title":600,"path":601,"description":602,"tags":603},"Node.js Memory Management","\u002Fblog\u002Fnodejs-memory-management","Node.js memory management provides means to dynamically allocate memory chunks for programs when they request them and free it when they are no longer needed, so they can be reused. Application-level memory management can be manual or automatic.",[16,17,442],{"title":605,"path":606,"description":607,"tags":608},"NODEJS PATTERNS","\u002Fblog\u002Fnodejs-patterns","A design pattern is a general, reusable solution to a commonly occurring problem. In this article we are going to look at some common design patterns we can use for Node.js.",[16,442],{"title":610,"path":611,"description":612,"tags":613},"NPM SCRIPTS","\u002Fblog\u002Fnpm-scripts","Task runners like Gulp or Grunt have been go to choice for the front end projects for last few years. Gulp being the latest between the two, and being the popular choice for last couple of years, one might wonder what’s wrong with it.",[16,17,442],{"title":615,"path":616,"description":617,"tags":618},"OPTIMIZING ASP.NET MVC SITES","\u002Fblog\u002Foptimizing-asp-net-mvc-sites","In this article we discuss about four ways of optimizing ASP.NET MVC sites",[16,184,619],"asp.net",{"title":621,"path":622,"description":623,"tags":624},"PHOTOSHOP CC NEW FEATURES","\u002Fblog\u002Fphotoshop-cc-new-features","Adobe Creative Cloud’s Photoshop CC  is packed with new tools and features, as well as some key workflow enhancements.",[9,112],{"title":626,"path":627,"description":628,"tags":629},"POSTCSS","\u002Fblog\u002Fpostcss","PostCSS is a tool for transforming CSS with JavaScript plugins. These plugins can support variables and mixins, transpile future CSS syntax, inline images, and more",[16,29],{"title":631,"path":632,"description":633,"tags":634},"PROPER TAIL CALLS","\u002Fblog\u002Fproper-tail-calls","A tail call happens when a function Foo calls a function Bar as its final action. At that point Foo stops and passes the execution to function Bar and disappears not having to do anything from there onwards.",[16,17],{"title":636,"path":637,"description":638,"tags":639},"PROXIES","\u002Fblog\u002Fproxies","Proxies enable you to intercept and customize actions performed on JavaScript objects such as `getter` and `setter` for getting and setting properties. This is really helpful in scenarios like JSON based API interaction where you have to customize data coming back from the API.",[16,17],{"title":641,"path":642,"description":643,"tags":644},"REACT BEST PRACTICES & PATTERNS","\u002Fblog\u002Freact-best-practices-patterns","In this article we discuss about React best practices & patterns for writing React components, and the recommendations here aim at coding convensions and patterns.",[16,17,140],{"title":646,"path":647,"description":648,"tags":649},"React Component Library with Material UI","\u002Fblog\u002Freact-component-library-with-material-ui","Using Material UI which supports Styled Components is an excellent combination of libraries to start building a design system of your own",[16,17,40,650],"material-ui",{"title":652,"path":653,"description":654,"tags":655},"REACT CONCURRENT MODE","\u002Fblog\u002Freact-concurrent-mode","'Regardless of all the optimizations we do in in React apps, rendering process so far has been a blocking and cannot be interrupted.",[16,40],{"title":657,"path":658,"description":659,"tags":660},"REACT CONTEXT API","\u002Fblog\u002Freact-context-api","The context API will finally become a first-class citizen with the release of React 16.3. Facebook has announced that they are going to release a stable yet revamped version of the context API.",[16,17,40],{"title":662,"path":663,"description":664,"tags":665},"REACT & CSS","\u002Fblog\u002Freact-css","In a scaling project, the way CSS spans out can bring us various problems. Let’s look at these issues, and discuss them in detail.",[16,17],{"title":667,"path":668,"description":669,"tags":670},"REACT DEPLOYMENT","\u002Fblog\u002Freact-deployment","In this article, we are discussing about how to perform a production deployment for React",[16,17,140],{"title":672,"path":673,"description":674,"tags":675},"REACT & ES6","\u002Fblog\u002Freact-es6","ES6 is here and now. So writing React JS components in ES6 will be beneficial considering the new features ES6 brings to us.",[16,17],{"title":677,"path":678,"description":679,"tags":680},"REACT & FLUX","\u002Fblog\u002Freact-flux","Flux is the application architecture that Facebook uses for building client-side web applications. It complements React’s composable view components by utilizing a unidirectional data flow. It’s more of a pattern rather than a formal framework.",[16,17,681],"raect.js",{"title":683,"path":684,"description":685,"tags":686},"REACT & NIGHTWATCH","\u002Fblog\u002Freact-nightwatch","Nightwatch is an end-to-end test framework. The reasons nightwatch is your best choice can be decided upon the reasons described in this article.",[16,17],{"title":688,"path":689,"description":690,"tags":691},"React Re-rendering Components","\u002Fblog\u002Freact-re-rendering-components","React is known for providing a fast user experience by only updating the parts of the UI that have changed. In this article, we discuss how we can optimise the render performance by understanding how React decides to re-render",[16,17,40],{"title":693,"path":694,"description":695,"tags":696},"REACT & REDUX","\u002Fblog\u002Freact-redux","'Redux allows you to manage the state with a minimal API but completely predictable behaviour – a predictable state container for JavaScript apps.",[16,17,140],{"title":698,"path":699,"description":700,"tags":701},"REACT ROUTER","\u002Fblog\u002Freact-router","React Router is the most popular routing library for React, which synchronizes your UI with the URL. It is built on top of React and helps you to build new screens quickly.",[16,17,140],{"title":703,"path":704,"description":705,"tags":706},"REACT STATELESS FUNCTIONAL COMPONENTS","\u002Fblog\u002Freact-stateless-functional-components","React stateless functional components are pure JavaScript functions that only have a render() function and no lifecycle methods like componentDidMount.",[16,17,140],{"title":708,"path":709,"description":710,"tags":711},"REACT V15","\u002Fblog\u002Freact-v15","Facebook released React v15.0.0 on 07\u002F04\u002F2016. The most noticeable change was the version number jump from 0.14 to 15.0.",[16,17,140],{"title":713,"path":714,"description":715,"tags":716},"REDUX & SAGAS","\u002Fblog\u002Fredux-sagas","In reality, for a real world application, just consuming an API end point and displaying the data is not going to cut it.",[16,17,140,717,718],"redux","redux-saga",{"title":720,"path":721,"description":722,"tags":723},"REQUIREJS & HANDLEBARS","\u002Fblog\u002Frequirejs-handlebars","If we are building a web application, code complexity could grow and the app can get bigger. Number of plug-ins can grow bigger, and you will feel the need of adding more modular components. RequireJS can address these issues to increase the speed of your application in an efficient way.",[16,17],{"title":725,"path":726,"description":727,"tags":728},"RESCUING THE DETAILS WITH TOPAZ LABS","\u002Fblog\u002Frescuing-details-topaz-labs","Here are the steps on how to recover shadows and make an image more vibrant with the Topaz Lab’s plug-ins.",[89],{"title":730,"path":731,"description":732,"tags":733},"RUBY API – REST ROUTES, CONSTRAINTS & NAMESPACES","\u002Fblog\u002Fruby-api-rest-routes-constraints-namespaces","In this article, we are going to study REST, routes, constraints, and namespaces. Before we dive into these concepts let’s take a look at how web-based services in the perspective of web users.",[16,124],{"title":735,"path":736,"description":737,"tags":738},"RUBY – INTRODUCTION","\u002Fblog\u002Fruby-introduction","Ruby is a dynamic, reflective, object-oriented, general-purpose programming language. It was designed and developed in the mid-1990s by Yukihiro “Matz” Matsumoto in Japan.",[16,124],{"title":740,"path":741,"description":742,"tags":743},"RUN COMMANDS FOR WINDOWS 7","\u002Fblog\u002Frun-commands-for-windows-7","A run command is the name of the file that starts an application, which is an executable for a program.",[361,744],"windows",{"title":746,"path":747,"description":748,"tags":749},"SAFARI CSS HACKS","\u002Fblog\u002Fsafari-css-hacks","Applying changes only for Safari has been always a challenging task. Also adding the fact that Safari has changed since version 6.1 makes it even harder. In this article we are going to discuss Safari CSS hacks.",[16,29,383],{"title":751,"path":752,"description":753,"tags":754},"SASS CONTROL DIRECTIVES","\u002Fblog\u002Fsass-control-directives","Sass control directives helps creating libraries for reuse and distribution, there by contribute to writing leaner Sass. Advanced frameworks use mixins. These mixins use directives such as @if, @for, each and @while.",[16,17],{"title":756,"path":757,"description":758,"tags":759},"SASS FOR CSS","\u002Fblog\u002Fsass-for-css","Sass is a scripting langauage that is interpreted into CSS. Sass stands for Syntatically Awesome Stylesheets.  Sass consists of two syntaxes. The original syntax, called “the indented syntax”, uses a syntax similar to Haml. It uses indentation to separate code blocks and newline characters to separate rules.",[16,29,292],{"title":761,"path":762,"description":763,"tags":764},"SASS INTRODUCTION","\u002Fblog\u002Fsass-introduction","CSS is crafted to be simple, but over time your styles become large and your files become bloated with selectors growing out of control. Scaling simplicity is difficult.",[16,17],{"title":766,"path":767,"description":768,"tags":769},"SASS – VARIABLES","\u002Fblog\u002Fsass-variables","Native CSS variable support is still in its infancy, but Sass affords us a way to set reusable values.",[16,29,292],{"title":771,"path":772,"description":773,"tags":774},"SECURING YOUR ASP.NET MVC 4 APPLICATION","\u002Fblog\u002Fsecuring-your-asp-net-mvc-4-application","Out of the Box when you create an MVC web site, anyone can post anything to your web site. So we need to control the user access.",[16,184,619],{"title":776,"path":777,"description":778,"tags":779},"SEMANTIC HTML","\u002Fblog\u002Fsemantic-hmtl","Semantic HTML is a way of describing the content of an HTML document, it is not a way of making your page look pretty or visually appealing.",[16,383],{"title":781,"path":782,"description":783,"tags":784},"SEND EMAIL IN UMBRACO","\u002Fblog\u002Fsend-email-in-umbraco","Sending email is a common functionality of any client-facing website. Is it possible to be implemented in Umbraco without a plugin? Yes, and I’m going to demonstrate how to implement such functionality.",[16,785,619],"umbraco",{"title":787,"path":788,"description":789,"tags":790},"Server Side Rendering with Suspense in React 18","\u002Fblog\u002Fserver-side-rendering-with-suspense-in-react-18","React 18 will include architectural improvements to React server-side rendering (SSR) performance.",[16,17,40,578],{"title":792,"path":793,"description":794,"tags":795},"SERVICE WORKERS","\u002Fblog\u002Fservice-workers","Service Worker is a new browser feature which provides event-driven scripts that run independently of web pages. Unlike other workers, Service Workers can be shut down at the end of events, note the lack of retained references from documents, and they have access to domain-wide events such as network fetches.",[16,17,796],"service-worker",{"title":798,"path":799,"description":800,"tags":801},"SETTING UP UMBRACO IN VISUAL STUDIO","\u002Fblog\u002Fsetting-up-umbraco-in-visual-studio","In this article we discuss about setting an Umbraco project with ASP.NET with step by step instructions",[16,619,785],{"title":803,"path":804,"description":805,"tags":806},"Should we declare React functional components with a const or a function?","\u002Fblog\u002Fshould-we-declare-react-functional-components-with-a-const-or-a-function","If you have been writing React functional components for a while now, you may have encountered two ways of declaring a component - an arrow function or a function declaration.",[16,17,807,40],"typesript",{"title":809,"path":810,"description":811,"tags":812},"SMACSS","\u002Fblog\u002Fsmacss","SMACSS stands for Scalable and Modular Architecture for CSS. It is pronounced “smacks” and introduced by Jonathan Snook.",[16,29,292],{"title":814,"path":815,"description":816,"tags":817},"STRUCTURE YOUR SASS","\u002Fblog\u002Fstructure-your-sass","Sass enables your you to separate your stylesheets into individual files, and then you can use the @import directive to include your individual files into one master stylesheet.",[16,29,292],{"title":819,"path":820,"description":821,"tags":822},"STYLUS FOR CSS","\u002Fblog\u002Fstylus-for-css","When your site grows, the CSS can grow along with it, and the maintenance is no longer  trivial. You could break your CSS in to different files and use @import to structure it into one file. But this doesn’t resolve all your architecting and maintenance problems. ",[16,29],{"title":824,"path":825,"description":826,"tags":827},"TAPE & TAP","\u002Fblog\u002Ftape-tap","Tape & Tap are testing tools you can use instead of Mocha or Jasmine. The Test Anything Protocol (TAP) is a definition that has been around since 1987 and Tape is a test harness written in JavaScript for Node and the browser.",[16,17,828],"testing",{"title":830,"path":831,"description":832,"tags":833},"TESTING REACT COMPONENTS WITH ENZYME","\u002Fblog\u002Ftesting-react-components-enzyme","React has become the framework of choice recently within the JavaScript community. And the tools for testing React components has also gained lot of attention.",[16,17,220],{"title":835,"path":836,"description":837,"tags":838},"THE MOST EXPENSIVE CAMERAS IN THE WORLD","\u002Fblog\u002Fthe-most-expensive-cameras-in-the-world","Digital photography has become a hobby that is more and more affordable in recent years, with the increase of hobbyist photographers to serious enthusiasts the camera and lens manufacturers have become competitive and innovative in releasing high specification products.",[89],{"title":840,"path":841,"description":842,"tags":843},"Things to avoid when using React Hooks","\u002Fblog\u002Fthings-to-avoid-when-using-react-hooks","In this article we discuss about a few things to avoid when writing React Hooks and forming good habits through understanding",[16,17,40],{"title":845,"path":846,"description":847,"tags":848},"THINK REACT","\u002Fblog\u002Fthink-react","As we know, React is a library for creating user interfaces. It renders your UI and responds to events aka: the V in MVC. Because it is not as opinionated as many of other front-end JavaScript libraries, it plays nicely with your stack, whatever it maybe, Ruby, Java, Node.js or .NET.",[16,17,140],{"title":850,"path":851,"description":852,"tags":853},"THROTTLE FUNCTION CALLS IN JAVASCRIPT","\u002Fblog\u002Fthrottle-function-calls-in-javascript","If you have written a search component that returns matching result as you type – you would realise that sending a request to the server on every key press is not required as that can result in burdening the server with too many requests.",[16,17],{"title":855,"path":856,"description":857,"tags":858},"Turborepo: The Next Big Thing in Build Systems","\u002Fblog\u002Fturborepo-the-next-big-thing-in-build-systems","Turborepo is a high-performance build system for JavaScript and TypeScript codebases. Vercel who acquired Turborepo claims, through incremental builds, intelligent remote caching, and optimized task scheduling, Turborepo can boost build speeds by 85% or more, enabling teams of all sizes to maintain a fast and efficient build system that scales as codebases and teams grow.",[16,17,859],"nodejs",{"title":861,"path":862,"description":863,"tags":864},"TypeScript Enums vs String Literals","\u002Fblog\u002Ftypescript-enums-vs-string-literals","Enums help to define a set of named constants. Using enums can make it easier to document intent, or create a set of distinct cases.",[16,17,807],{"title":866,"path":867,"description":868,"tags":869},"TypeScript Features You Should No Longer Use","\u002Fblog\u002Ftypescript-features-you-should-no-longer-use","When TypeScript was originally invented by Microsoft in 2010, they implemented features missing from JavaScript at the time including module systems, classes, enums and decorators.",[16,17,870],"typescript",{"title":872,"path":873,"description":874,"tags":875},"Understanding cloneElement, isValidElement and Render Props","\u002Fblog\u002Funderstanding-cloneelement-isvalidelement-and-render-props","React provides several APIs for transforming elements: cloneElement, isValidElement.",[16,17,40],{"title":877,"path":878,"description":879,"tags":880},"UNITS FOR CSS FONT-SIZE","\u002Fblog\u002Funits-for-css-font-size","Fonts sizes in CSS can be measured in four different units adding confusion to the web developer on top of having to deal with different browsers. Which of these four units is the best? Finding a definitive answer is difficult.",[16,29],{"title":882,"path":883,"description":884,"tags":885},"USING ES6 WITH BABEL","\u002Fblog\u002Fusing-es6-babel","Some of the modern browsers are yet to catch up with the new language additions to ES6. This means we have to use Babel to transpile our code into ES5.",[16,17,220],{"title":887,"path":888,"description":889,"tags":890},"VIRTUAL DOM","\u002Fblog\u002Fvirtual-dom","If you are using React, there is a better chance you have heard about virtual DOM. In a nutshell, virtual DOM is an abstract version of the DOM, a lightweight copy of the actual DOM which we can manipulate the way we want and then apply to the DOM tree.",[16,17],{"title":242,"path":892,"description":893,"tags":894},"\u002Fblog\u002Fweb-application-security","'Cyber security has become a necessity for any web developer building client-facing web applications.",[16,895],"security",{"title":897,"path":898,"description":899,"tags":900},"WEB PAGE RENDERING","\u002Fblog\u002Fweb-page-rendering","'Web page rendering is an important subject to study in order to optimize page load times, and to understand how to design solutions to cater for that.",[16,17,29,383],{"title":902,"path":903,"description":904,"tags":905},"WEBPACK EXPORT MODULES","\u002Fblog\u002Fwebpack-export-modules","You may be working in a complex project, where multiple isolated modules need to be imported into a single parent module, you might want to configure Webpack.config to enable exporting modules.",[16,17],{"title":907,"path":908,"description":909,"tags":910},"WHAT IS AGILE PROJECT MANAGEMENT?","\u002Fblog\u002Fwhat-is-agile-project-management","Agile project management allows you to produce a smaller amount of deliverables more frequently and efficiently , making it an excellent choice for the teams that are working in the field of  business analysis, product development, programming , and other areas of collaboration.",[16,911],"agile",{"title":913,"path":914,"description":915,"tags":916},"WRITING FORMS IN REACT AND REDUX","\u002Fblog\u002Fwriting-forms-react","rWiting forms in React and Redux can be challenging, having to deal with forms and fields. In this article we are going to build couple of form using an exisiting library sepcifically for Redux called react-redux-form.",[16,29,383],{"id":918,"title":58,"author":919,"body":920,"date":6082,"description":60,"extension":6083,"image":6084,"meta":6085,"navigation":1116,"path":59,"seo":6086,"stem":6087,"tags":6088,"__hash__":6089},"blog\u002Fblog\u002Fbackbone-patterns.md","Sean Amarasinghe",{"type":921,"value":922,"toc":6059},"minimark",[923,928,933,937,940,948,1238,1241,1564,1574,1577,1581,1584,1616,1633,1669,1686,1697,1798,1805,1841,1846,1878,1891,2028,2031,2150,2153,2156,2181,2205,2212,2216,2223,2364,2375,2714,2777,2780,3061,3064,3067,3070,3074,3077,3253,3256,3264,3496,3512,3516,3536,3539,3548,3552,3562,3588,3597,3758,3761,3764,3974,3981,3985,4016,4178,4182,4195,4205,4215,4379,4382,4386,4389,4393,4396,4657,4668,4672,4675,4871,4874,4877,4881,4889,4893,4896,5066,5080,5150,5154,5162,5337,5341,5344,5495,5498,5646,5652,5853,5857,5866,6012,6033,6037,6052,6055],[924,925,927],"h2",{"id":926},"create-façades-to-objects","Create Façades To Objects",[929,930,932],"h3",{"id":931},"getters-setters","Getters & Setters",[934,935,936],"p",{},"When requirements change often, JSON returned by the endpoints that your models and collections hit needs to change as well. This can become a really big pain point in your codebase if your view is tightly coupled to the underlying data model - comes getters and setters for all objects.",[934,938,939],{},"The pros of this pattern are many. If any of the underlying data structures change, then the view layers shouldn’t have to update that much; you will have one point of access to the data, so you are less likely to forget to do a deep copy, and your code will be more maintainable and much easier to debug. The downside is that this pattern can cause a bit of bloat in your models or collections.",[934,941,942,943,947],{},"Let’s look at an example to illustrate this pattern. Imagine we have a ",[944,945,946],"code",{},"Cinema"," model that contains rooms and the currently available rooms, and that we want to be able to retrieve rooms by seat price.",[949,950,955],"pre",{"className":951,"code":952,"language":953,"meta":954,"style":954},"language-js shiki shiki-themes github-light github-dark","var Cinema = Backbone.Model.extend({\n  defaults: {\n    availableRooms: ['a'],\n    rooms: {\n      a: {\n        price: 1200,\n        seat: 'back',\n      },\n      b: {\n        price: 900,\n        seat: 'middle',\n      },\n      c: {\n        price: 1100,\n        seat: 'middle',\n      },\n    },\n\n    getRooms: function () {\n      $.extend(true, {}, this.get('rooms'));\n    },\n\n    getRoomsByBed: function (seat) {\n      return _.where(this.getRooms(), { seat: seat });\n    },\n  },\n});\n","js","",[944,956,957,983,989,1002,1008,1014,1027,1038,1044,1050,1060,1070,1075,1081,1091,1100,1105,1111,1118,1133,1167,1172,1177,1197,1221,1226,1232],{"__ignoreMap":954},[958,959,962,966,970,973,976,980],"span",{"class":960,"line":961},"line",1,[958,963,965],{"class":964},"szBVR","var",[958,967,969],{"class":968},"sVt8B"," Cinema ",[958,971,972],{"class":964},"=",[958,974,975],{"class":968}," Backbone.Model.",[958,977,979],{"class":978},"sScJk","extend",[958,981,982],{"class":968},"({\n",[958,984,986],{"class":960,"line":985},2,[958,987,988],{"class":968},"  defaults: {\n",[958,990,992,995,999],{"class":960,"line":991},3,[958,993,994],{"class":968},"    availableRooms: [",[958,996,998],{"class":997},"sZZnC","'a'",[958,1000,1001],{"class":968},"],\n",[958,1003,1005],{"class":960,"line":1004},4,[958,1006,1007],{"class":968},"    rooms: {\n",[958,1009,1011],{"class":960,"line":1010},5,[958,1012,1013],{"class":968},"      a: {\n",[958,1015,1017,1020,1024],{"class":960,"line":1016},6,[958,1018,1019],{"class":968},"        price: ",[958,1021,1023],{"class":1022},"sj4cs","1200",[958,1025,1026],{"class":968},",\n",[958,1028,1030,1033,1036],{"class":960,"line":1029},7,[958,1031,1032],{"class":968},"        seat: ",[958,1034,1035],{"class":997},"'back'",[958,1037,1026],{"class":968},[958,1039,1041],{"class":960,"line":1040},8,[958,1042,1043],{"class":968},"      },\n",[958,1045,1047],{"class":960,"line":1046},9,[958,1048,1049],{"class":968},"      b: {\n",[958,1051,1053,1055,1058],{"class":960,"line":1052},10,[958,1054,1019],{"class":968},[958,1056,1057],{"class":1022},"900",[958,1059,1026],{"class":968},[958,1061,1063,1065,1068],{"class":960,"line":1062},11,[958,1064,1032],{"class":968},[958,1066,1067],{"class":997},"'middle'",[958,1069,1026],{"class":968},[958,1071,1073],{"class":960,"line":1072},12,[958,1074,1043],{"class":968},[958,1076,1078],{"class":960,"line":1077},13,[958,1079,1080],{"class":968},"      c: {\n",[958,1082,1084,1086,1089],{"class":960,"line":1083},14,[958,1085,1019],{"class":968},[958,1087,1088],{"class":1022},"1100",[958,1090,1026],{"class":968},[958,1092,1094,1096,1098],{"class":960,"line":1093},15,[958,1095,1032],{"class":968},[958,1097,1067],{"class":997},[958,1099,1026],{"class":968},[958,1101,1103],{"class":960,"line":1102},16,[958,1104,1043],{"class":968},[958,1106,1108],{"class":960,"line":1107},17,[958,1109,1110],{"class":968},"    },\n",[958,1112,1114],{"class":960,"line":1113},18,[958,1115,1117],{"emptyLinePlaceholder":1116},true,"\n",[958,1119,1121,1124,1127,1130],{"class":960,"line":1120},19,[958,1122,1123],{"class":978},"    getRooms",[958,1125,1126],{"class":968},": ",[958,1128,1129],{"class":964},"function",[958,1131,1132],{"class":968}," () {\n",[958,1134,1136,1139,1141,1144,1147,1150,1153,1156,1159,1161,1164],{"class":960,"line":1135},20,[958,1137,1138],{"class":968},"      $.",[958,1140,979],{"class":978},[958,1142,1143],{"class":968},"(",[958,1145,1146],{"class":1022},"true",[958,1148,1149],{"class":968},", {}, ",[958,1151,1152],{"class":1022},"this",[958,1154,1155],{"class":968},".",[958,1157,1158],{"class":978},"get",[958,1160,1143],{"class":968},[958,1162,1163],{"class":997},"'rooms'",[958,1165,1166],{"class":968},"));\n",[958,1168,1170],{"class":960,"line":1169},21,[958,1171,1110],{"class":968},[958,1173,1175],{"class":960,"line":1174},22,[958,1176,1117],{"emptyLinePlaceholder":1116},[958,1178,1180,1183,1185,1187,1190,1194],{"class":960,"line":1179},23,[958,1181,1182],{"class":978},"    getRoomsByBed",[958,1184,1126],{"class":968},[958,1186,1129],{"class":964},[958,1188,1189],{"class":968}," (",[958,1191,1193],{"class":1192},"s4XuR","seat",[958,1195,1196],{"class":968},") {\n",[958,1198,1200,1203,1206,1209,1211,1213,1215,1218],{"class":960,"line":1199},24,[958,1201,1202],{"class":964},"      return",[958,1204,1205],{"class":968}," _.",[958,1207,1208],{"class":978},"where",[958,1210,1143],{"class":968},[958,1212,1152],{"class":1022},[958,1214,1155],{"class":968},[958,1216,1217],{"class":978},"getRooms",[958,1219,1220],{"class":968},"(), { seat: seat });\n",[958,1222,1224],{"class":960,"line":1223},25,[958,1225,1110],{"class":968},[958,1227,1229],{"class":960,"line":1228},26,[958,1230,1231],{"class":968},"  },\n",[958,1233,1235],{"class":960,"line":1234},27,[958,1236,1237],{"class":968},"});\n",[934,1239,1240],{},"Now let’s imagine that tomorrow you will be releasing your code, and you find out that the endpoint developers forgot to tell you that the data structure of rooms has changed from an object to an array. Your code now looks like the following.",[949,1242,1244],{"className":951,"code":1243,"language":953,"meta":954,"style":954},"var Cinema = Backbone.Model.extend({\n  defaults: {\n    availableRooms: ['a'],\n    rooms: [\n      {\n        name: 'a',\n        price: 1200,\n        seat: 'back',\n      },\n      {\n        name: 'b',\n        price: 900,\n        seat: 'middle',\n      },\n      {\n        name: 'c',\n        price: 1100,\n        seat: 'middle',\n      },\n    ],\n\n    getRooms: function () {\n      var rooms = $.extend(true, {}, this.get('rooms')),\n        newRooms = {};\n\n      \u002F\u002F transform rooms from an array back into an object\n      _.each(rooms, function (room) {\n        newRooms[room.name] = {\n          price: room.price,\n          seat: room.seat,\n        };\n      });\n    },\n\n    getRoomsByBed: function (seat) {\n      return _.where(this.getRooms(), { seat: seat });\n    },\n  },\n});\n",[944,1245,1246,1260,1264,1272,1277,1282,1291,1299,1307,1311,1315,1324,1332,1340,1344,1348,1357,1365,1373,1377,1382,1386,1396,1430,1440,1444,1450,1470,1481,1487,1493,1499,1505,1510,1515,1530,1549,1554,1559],{"__ignoreMap":954},[958,1247,1248,1250,1252,1254,1256,1258],{"class":960,"line":961},[958,1249,965],{"class":964},[958,1251,969],{"class":968},[958,1253,972],{"class":964},[958,1255,975],{"class":968},[958,1257,979],{"class":978},[958,1259,982],{"class":968},[958,1261,1262],{"class":960,"line":985},[958,1263,988],{"class":968},[958,1265,1266,1268,1270],{"class":960,"line":991},[958,1267,994],{"class":968},[958,1269,998],{"class":997},[958,1271,1001],{"class":968},[958,1273,1274],{"class":960,"line":1004},[958,1275,1276],{"class":968},"    rooms: [\n",[958,1278,1279],{"class":960,"line":1010},[958,1280,1281],{"class":968},"      {\n",[958,1283,1284,1287,1289],{"class":960,"line":1016},[958,1285,1286],{"class":968},"        name: ",[958,1288,998],{"class":997},[958,1290,1026],{"class":968},[958,1292,1293,1295,1297],{"class":960,"line":1029},[958,1294,1019],{"class":968},[958,1296,1023],{"class":1022},[958,1298,1026],{"class":968},[958,1300,1301,1303,1305],{"class":960,"line":1040},[958,1302,1032],{"class":968},[958,1304,1035],{"class":997},[958,1306,1026],{"class":968},[958,1308,1309],{"class":960,"line":1046},[958,1310,1043],{"class":968},[958,1312,1313],{"class":960,"line":1052},[958,1314,1281],{"class":968},[958,1316,1317,1319,1322],{"class":960,"line":1062},[958,1318,1286],{"class":968},[958,1320,1321],{"class":997},"'b'",[958,1323,1026],{"class":968},[958,1325,1326,1328,1330],{"class":960,"line":1072},[958,1327,1019],{"class":968},[958,1329,1057],{"class":1022},[958,1331,1026],{"class":968},[958,1333,1334,1336,1338],{"class":960,"line":1077},[958,1335,1032],{"class":968},[958,1337,1067],{"class":997},[958,1339,1026],{"class":968},[958,1341,1342],{"class":960,"line":1083},[958,1343,1043],{"class":968},[958,1345,1346],{"class":960,"line":1093},[958,1347,1281],{"class":968},[958,1349,1350,1352,1355],{"class":960,"line":1102},[958,1351,1286],{"class":968},[958,1353,1354],{"class":997},"'c'",[958,1356,1026],{"class":968},[958,1358,1359,1361,1363],{"class":960,"line":1107},[958,1360,1019],{"class":968},[958,1362,1088],{"class":1022},[958,1364,1026],{"class":968},[958,1366,1367,1369,1371],{"class":960,"line":1113},[958,1368,1032],{"class":968},[958,1370,1067],{"class":997},[958,1372,1026],{"class":968},[958,1374,1375],{"class":960,"line":1120},[958,1376,1043],{"class":968},[958,1378,1379],{"class":960,"line":1135},[958,1380,1381],{"class":968},"    ],\n",[958,1383,1384],{"class":960,"line":1169},[958,1385,1117],{"emptyLinePlaceholder":1116},[958,1387,1388,1390,1392,1394],{"class":960,"line":1174},[958,1389,1123],{"class":978},[958,1391,1126],{"class":968},[958,1393,1129],{"class":964},[958,1395,1132],{"class":968},[958,1397,1398,1401,1404,1406,1409,1411,1413,1415,1417,1419,1421,1423,1425,1427],{"class":960,"line":1179},[958,1399,1400],{"class":964},"      var",[958,1402,1403],{"class":968}," rooms ",[958,1405,972],{"class":964},[958,1407,1408],{"class":968}," $.",[958,1410,979],{"class":978},[958,1412,1143],{"class":968},[958,1414,1146],{"class":1022},[958,1416,1149],{"class":968},[958,1418,1152],{"class":1022},[958,1420,1155],{"class":968},[958,1422,1158],{"class":978},[958,1424,1143],{"class":968},[958,1426,1163],{"class":997},[958,1428,1429],{"class":968},")),\n",[958,1431,1432,1435,1437],{"class":960,"line":1199},[958,1433,1434],{"class":968},"        newRooms ",[958,1436,972],{"class":964},[958,1438,1439],{"class":968}," {};\n",[958,1441,1442],{"class":960,"line":1223},[958,1443,1117],{"emptyLinePlaceholder":1116},[958,1445,1446],{"class":960,"line":1228},[958,1447,1449],{"class":1448},"sJ8bj","      \u002F\u002F transform rooms from an array back into an object\n",[958,1451,1452,1455,1458,1461,1463,1465,1468],{"class":960,"line":1234},[958,1453,1454],{"class":968},"      _.",[958,1456,1457],{"class":978},"each",[958,1459,1460],{"class":968},"(rooms, ",[958,1462,1129],{"class":964},[958,1464,1189],{"class":968},[958,1466,1467],{"class":1192},"room",[958,1469,1196],{"class":968},[958,1471,1473,1476,1478],{"class":960,"line":1472},28,[958,1474,1475],{"class":968},"        newRooms[room.name] ",[958,1477,972],{"class":964},[958,1479,1480],{"class":968}," {\n",[958,1482,1484],{"class":960,"line":1483},29,[958,1485,1486],{"class":968},"          price: room.price,\n",[958,1488,1490],{"class":960,"line":1489},30,[958,1491,1492],{"class":968},"          seat: room.seat,\n",[958,1494,1496],{"class":960,"line":1495},31,[958,1497,1498],{"class":968},"        };\n",[958,1500,1502],{"class":960,"line":1501},32,[958,1503,1504],{"class":968},"      });\n",[958,1506,1508],{"class":960,"line":1507},33,[958,1509,1110],{"class":968},[958,1511,1513],{"class":960,"line":1512},34,[958,1514,1117],{"emptyLinePlaceholder":1116},[958,1516,1518,1520,1522,1524,1526,1528],{"class":960,"line":1517},35,[958,1519,1182],{"class":978},[958,1521,1126],{"class":968},[958,1523,1129],{"class":964},[958,1525,1189],{"class":968},[958,1527,1193],{"class":1192},[958,1529,1196],{"class":968},[958,1531,1533,1535,1537,1539,1541,1543,1545,1547],{"class":960,"line":1532},36,[958,1534,1202],{"class":964},[958,1536,1205],{"class":968},[958,1538,1208],{"class":978},[958,1540,1143],{"class":968},[958,1542,1152],{"class":1022},[958,1544,1155],{"class":968},[958,1546,1217],{"class":978},[958,1548,1220],{"class":968},[958,1550,1552],{"class":960,"line":1551},37,[958,1553,1110],{"class":968},[958,1555,1557],{"class":960,"line":1556},38,[958,1558,1231],{"class":968},[958,1560,1562],{"class":960,"line":1561},39,[958,1563,1237],{"class":968},[934,1565,1566,1567,1569,1570,1573],{},"We updated only one function in order to transform the ",[944,1568,946],{}," structure into the structure that the rest of our application expects, and our entire app still behaves as expected. If we didn’t have a getter here, we might potentially have to update each point of access to ",[944,1571,1572],{},"rooms",". Ideally, you would want to update all of your functions to work with the new data structure, but if you’re pressed for time and have to release, this pattern can save you.",[934,1575,1576],{},"As an aside, this pattern can be thought of as both a facade design pattern, because it hides the complexity of creating a copy of your objects, or a bridge design pattern, because it can be used to transform data into what is expected. A good rule of thumb is to use getters and setters on anything that is an object.",[924,1578,1580],{"id":1579},"perform-deep-copies-of-objects","Perform Deep Copies Of Objects",[934,1582,1583],{},"JavaScript treats all primitive-type variables as pass-by-value. So, the value of a variable is passed when the variable is referenced.",[949,1585,1587],{"className":951,"code":1586,"language":953,"meta":954,"style":954},"var firstName = *Hello World”;\nvar helloWorldCopy = helloWorld;\n",[944,1588,1589,1604],{"__ignoreMap":954},[958,1590,1591,1593,1596,1598,1601],{"class":960,"line":961},[958,1592,965],{"class":964},[958,1594,1595],{"class":968}," firstName ",[958,1597,972],{"class":964},[958,1599,1600],{"class":964}," *",[958,1602,1603],{"class":968},"Hello World”;\n",[958,1605,1606,1608,1611,1613],{"class":960,"line":985},[958,1607,965],{"class":964},[958,1609,1610],{"class":968}," helloWorldCopy ",[958,1612,972],{"class":964},[958,1614,1615],{"class":968}," helloWorld;\n",[934,1617,1618,1619,1622,1623,1626,1627,1629,1630,1632],{},"For example, the code above will set ",[944,1620,1621],{},"helloWorldCopy"," equal to the value of ",[944,1624,1625],{},"helloWorld",". So, any modification to ",[944,1628,1621],{}," will not modify ",[944,1631,1625],{},", since it is a copy. JavaScript treats all non-primitive type variables as pass-by-reference, meaning that JavaScript will pass a reference of the memory address of the variable when the variable is referenced.",[949,1634,1636],{"className":951,"code":1635,"language":953,"meta":954,"style":954},"var helloWorld = {\n    ‘hello’: ‘world’\n}\nvar helloWorldCopy = helloWorld;\n",[944,1637,1638,1649,1654,1659],{"__ignoreMap":954},[958,1639,1640,1642,1645,1647],{"class":960,"line":961},[958,1641,965],{"class":964},[958,1643,1644],{"class":968}," helloWorld ",[958,1646,972],{"class":964},[958,1648,1480],{"class":968},[958,1650,1651],{"class":960,"line":985},[958,1652,1653],{"class":968},"    ‘hello’: ‘world’\n",[958,1655,1656],{"class":960,"line":991},[958,1657,1658],{"class":968},"}\n",[958,1660,1661,1663,1665,1667],{"class":960,"line":1004},[958,1662,965],{"class":964},[958,1664,1610],{"class":968},[958,1666,972],{"class":964},[958,1668,1615],{"class":968},[934,1670,1618,1671,1673,1674,1676,1677,1679,1680,1682,1683,1685],{},[944,1672,1621],{}," equal to the reference of",[944,1675,1625],{},", and, as you might guess, any modifications to ",[944,1678,1621],{}," would directly manipulate ",[944,1681,1625],{},". If you’d like to have a copy of the ",[944,1684,1625],{},", you will have to create a copy of the object.",[934,1687,1688,1689,1692,1693,1696],{},"You’re probably wondering, *Why is he explaining all of this pass-by-reference stuff?” Well, Backbone.js does not copy objects, which means that if you",[944,1690,1691],{},".get()"," an object from a model, any modifications to that object will directly manipulate the object! Let’s look at an example to illustrate where this can become an issue. Let’s say you have a ",[944,1694,1695],{},"Person"," model like the following:",[949,1698,1700],{"className":951,"code":1699,"language":953,"meta":954,"style":954},"var Person = Backbone.Model.extend({\n   defaults: {\n        'name': 'John Doe',\n        'address': {\n            'street': '1st Street'\n            'city': 'Austin',\n            'state': 'TX'\n            'zipCode': 78701\n        }\n   }\n});\n",[944,1701,1702,1717,1722,1734,1742,1752,1764,1774,1784,1789,1794],{"__ignoreMap":954},[958,1703,1704,1706,1709,1711,1713,1715],{"class":960,"line":961},[958,1705,965],{"class":964},[958,1707,1708],{"class":968}," Person ",[958,1710,972],{"class":964},[958,1712,975],{"class":968},[958,1714,979],{"class":978},[958,1716,982],{"class":968},[958,1718,1719],{"class":960,"line":985},[958,1720,1721],{"class":968},"   defaults: {\n",[958,1723,1724,1727,1729,1732],{"class":960,"line":991},[958,1725,1726],{"class":997},"        'name'",[958,1728,1126],{"class":968},[958,1730,1731],{"class":997},"'John Doe'",[958,1733,1026],{"class":968},[958,1735,1736,1739],{"class":960,"line":1004},[958,1737,1738],{"class":997},"        'address'",[958,1740,1741],{"class":968},": {\n",[958,1743,1744,1747,1749],{"class":960,"line":1010},[958,1745,1746],{"class":997},"            'street'",[958,1748,1126],{"class":968},[958,1750,1751],{"class":997},"'1st Street'\n",[958,1753,1754,1757,1759,1762],{"class":960,"line":1016},[958,1755,1756],{"class":997},"            'city'",[958,1758,1126],{"class":968},[958,1760,1761],{"class":997},"'Austin'",[958,1763,1026],{"class":968},[958,1765,1766,1769,1771],{"class":960,"line":1029},[958,1767,1768],{"class":997},"            'state'",[958,1770,1126],{"class":968},[958,1772,1773],{"class":997},"'TX'\n",[958,1775,1776,1779,1781],{"class":960,"line":1040},[958,1777,1778],{"class":997},"            'zipCode'",[958,1780,1126],{"class":968},[958,1782,1783],{"class":1022},"78701\n",[958,1785,1786],{"class":960,"line":1046},[958,1787,1788],{"class":968},"        }\n",[958,1790,1791],{"class":960,"line":1052},[958,1792,1793],{"class":968},"   }\n",[958,1795,1796],{"class":960,"line":1062},[958,1797,1237],{"class":968},[934,1799,1800,1801,1804],{},"And let’s say you create a new ",[944,1802,1803],{},"person"," object:",[949,1806,1808],{"className":951,"code":1807,"language":953,"meta":954,"style":954},"var person = new Person({\n  name: 'Phillip W',\n});\n",[944,1809,1810,1827,1837],{"__ignoreMap":954},[958,1811,1812,1814,1817,1819,1822,1825],{"class":960,"line":961},[958,1813,965],{"class":964},[958,1815,1816],{"class":968}," person ",[958,1818,972],{"class":964},[958,1820,1821],{"class":964}," new",[958,1823,1824],{"class":978}," Person",[958,1826,982],{"class":968},[958,1828,1829,1832,1835],{"class":960,"line":985},[958,1830,1831],{"class":968},"  name: ",[958,1833,1834],{"class":997},"'Phillip W'",[958,1836,1026],{"class":968},[958,1838,1839],{"class":960,"line":991},[958,1840,1237],{"class":968},[934,1842,1843,1844,1804],{},"Now, let’s manipulate some of the attributes of the new ",[944,1845,1803],{},[949,1847,1849],{"className":951,"code":1848,"language":953,"meta":954,"style":954},"person.set('name', 'Phillip W.', { validate: true });\n",[944,1850,1851],{"__ignoreMap":954},[958,1852,1853,1856,1859,1861,1864,1867,1870,1873,1875],{"class":960,"line":961},[958,1854,1855],{"class":968},"person.",[958,1857,1858],{"class":978},"set",[958,1860,1143],{"class":968},[958,1862,1863],{"class":997},"'name'",[958,1865,1866],{"class":968},", ",[958,1868,1869],{"class":997},"'Phillip W.'",[958,1871,1872],{"class":968},", { validate: ",[958,1874,1146],{"class":1022},[958,1876,1877],{"class":968}," });\n",[934,1879,1880,1881,1884,1885,1887,1888,1890],{},"The code above successfully manipulates the ",[944,1882,1883],{},"name"," attribute of the ",[944,1886,1803],{},"object. Now let’s try to manipulate the address of the ",[944,1889,1803],{}," object. However, before doing so, let’s add some validation for the address.",[949,1892,1894],{"className":951,"code":1893,"language":953,"meta":954,"style":954},"var Person = Backbone.Model.extend({\n    validate: function(attributes) {\n\n        if(isNaN(attributes.address.zipCode)) return \"Address ZIP code must be a number!\";\n    },\n\n    defaults: {\n        'name': 'John Doe',\n        'address': {\n            'street': '1st Street'\n            'city': 'Austin',\n            'state': 'TX'\n            'zipCode': 78701\n        }\n    }\n});\n",[944,1895,1896,1910,1926,1930,1952,1956,1960,1965,1975,1981,1989,1999,2007,2015,2019,2024],{"__ignoreMap":954},[958,1897,1898,1900,1902,1904,1906,1908],{"class":960,"line":961},[958,1899,965],{"class":964},[958,1901,1708],{"class":968},[958,1903,972],{"class":964},[958,1905,975],{"class":968},[958,1907,979],{"class":978},[958,1909,982],{"class":968},[958,1911,1912,1915,1917,1919,1921,1924],{"class":960,"line":985},[958,1913,1914],{"class":978},"    validate",[958,1916,1126],{"class":968},[958,1918,1129],{"class":964},[958,1920,1143],{"class":968},[958,1922,1923],{"class":1192},"attributes",[958,1925,1196],{"class":968},[958,1927,1928],{"class":960,"line":991},[958,1929,1117],{"emptyLinePlaceholder":1116},[958,1931,1932,1935,1937,1940,1943,1946,1949],{"class":960,"line":1004},[958,1933,1934],{"class":964},"        if",[958,1936,1143],{"class":968},[958,1938,1939],{"class":978},"isNaN",[958,1941,1942],{"class":968},"(attributes.address.zipCode)) ",[958,1944,1945],{"class":964},"return",[958,1947,1948],{"class":997}," \"Address ZIP code must be a number!\"",[958,1950,1951],{"class":968},";\n",[958,1953,1954],{"class":960,"line":1010},[958,1955,1110],{"class":968},[958,1957,1958],{"class":960,"line":1016},[958,1959,1117],{"emptyLinePlaceholder":1116},[958,1961,1962],{"class":960,"line":1029},[958,1963,1964],{"class":968},"    defaults: {\n",[958,1966,1967,1969,1971,1973],{"class":960,"line":1040},[958,1968,1726],{"class":997},[958,1970,1126],{"class":968},[958,1972,1731],{"class":997},[958,1974,1026],{"class":968},[958,1976,1977,1979],{"class":960,"line":1046},[958,1978,1738],{"class":997},[958,1980,1741],{"class":968},[958,1982,1983,1985,1987],{"class":960,"line":1052},[958,1984,1746],{"class":997},[958,1986,1126],{"class":968},[958,1988,1751],{"class":997},[958,1990,1991,1993,1995,1997],{"class":960,"line":1062},[958,1992,1756],{"class":997},[958,1994,1126],{"class":968},[958,1996,1761],{"class":997},[958,1998,1026],{"class":968},[958,2000,2001,2003,2005],{"class":960,"line":1072},[958,2002,1768],{"class":997},[958,2004,1126],{"class":968},[958,2006,1773],{"class":997},[958,2008,2009,2011,2013],{"class":960,"line":1077},[958,2010,1778],{"class":997},[958,2012,1126],{"class":968},[958,2014,1783],{"class":1022},[958,2016,2017],{"class":960,"line":1083},[958,2018,1788],{"class":968},[958,2020,2021],{"class":960,"line":1093},[958,2022,2023],{"class":968},"    }\n",[958,2025,2026],{"class":960,"line":1102},[958,2027,1237],{"class":968},[934,2029,2030],{},"Now, let’s attempt to manipulate the address with an incorrect ZIP code.",[949,2032,2034],{"className":951,"code":2033,"language":953,"meta":954,"style":954},"var address = person.get('address');\naddress.zipCode = 'Hello World';\n\u002F\u002F Raises an error since the ZIP code is invalid\nperson.set('address', address, { validate: true });\nconsole.log(person.get('address'));\n\u002F* Prints an object with these properties.\n{\n    'street': '1st Street'\n    'city': 'Austin',\n    'state': 'TX'\n    'zipCode': 'Hello World'\n}\n*\u002F\n",[944,2035,2036,2058,2070,2075,2092,2111,2116,2121,2126,2131,2136,2141,2145],{"__ignoreMap":954},[958,2037,2038,2040,2043,2045,2048,2050,2052,2055],{"class":960,"line":961},[958,2039,965],{"class":964},[958,2041,2042],{"class":968}," address ",[958,2044,972],{"class":964},[958,2046,2047],{"class":968}," person.",[958,2049,1158],{"class":978},[958,2051,1143],{"class":968},[958,2053,2054],{"class":997},"'address'",[958,2056,2057],{"class":968},");\n",[958,2059,2060,2063,2065,2068],{"class":960,"line":985},[958,2061,2062],{"class":968},"address.zipCode ",[958,2064,972],{"class":964},[958,2066,2067],{"class":997}," 'Hello World'",[958,2069,1951],{"class":968},[958,2071,2072],{"class":960,"line":991},[958,2073,2074],{"class":1448},"\u002F\u002F Raises an error since the ZIP code is invalid\n",[958,2076,2077,2079,2081,2083,2085,2088,2090],{"class":960,"line":1004},[958,2078,1855],{"class":968},[958,2080,1858],{"class":978},[958,2082,1143],{"class":968},[958,2084,2054],{"class":997},[958,2086,2087],{"class":968},", address, { validate: ",[958,2089,1146],{"class":1022},[958,2091,1877],{"class":968},[958,2093,2094,2097,2100,2103,2105,2107,2109],{"class":960,"line":1010},[958,2095,2096],{"class":968},"console.",[958,2098,2099],{"class":978},"log",[958,2101,2102],{"class":968},"(person.",[958,2104,1158],{"class":978},[958,2106,1143],{"class":968},[958,2108,2054],{"class":997},[958,2110,1166],{"class":968},[958,2112,2113],{"class":960,"line":1016},[958,2114,2115],{"class":1448},"\u002F* Prints an object with these properties.\n",[958,2117,2118],{"class":960,"line":1029},[958,2119,2120],{"class":1448},"{\n",[958,2122,2123],{"class":960,"line":1040},[958,2124,2125],{"class":1448},"    'street': '1st Street'\n",[958,2127,2128],{"class":960,"line":1046},[958,2129,2130],{"class":1448},"    'city': 'Austin',\n",[958,2132,2133],{"class":960,"line":1052},[958,2134,2135],{"class":1448},"    'state': 'TX'\n",[958,2137,2138],{"class":960,"line":1062},[958,2139,2140],{"class":1448},"    'zipCode': 'Hello World'\n",[958,2142,2143],{"class":960,"line":1072},[958,2144,1658],{"class":1448},[958,2146,2147],{"class":960,"line":1077},[958,2148,2149],{"class":1448},"*\u002F\n",[934,2151,2152],{},"How can this be? Our validation has raised an error! Why are the attributes still changed? As mentioned, Backbone.js does not copy model attributes; it simply returns whatever you’re asking for. So, as you might guess, if you ask for an object, you will get a reference to that object, and any manipulation to the object will directly manipulate the actual object in the model. This can quickly lead you down a very dark rabbit hole that can take you hours of debugging to diagnose.",[934,2154,2155],{},"This issue catches developers who are new to Backbone.js and even seasoned JavaScript developers off guard. This issue has been heavily discussed in the GitHub issues section of Backbone.js. As Jeremy Ashkenas points out there, performing a deep copy is a very difficult problem to solve, and it can become an expensive operation for very large, deep objects.",[934,2157,2158,2159,2162,2163,2166,2167,2170,2171,2174,2175,2177,2178,2180],{},"Luckily, jQuery provides an implementation of deep copying, ",[944,2160,2161],{},"$.``extend",". As an aside, Underscore.js, a dependency of Backbone.js, provides the ",[944,2164,2165],{},"_.extend ","function, but I would avoid using it because it does not perform a deep copy. Lo-Dash, a forked and optimized version of Underscore.js, provides a ",[944,2168,2169],{},"_.clone ","function with the option to perform a deep copy. However, I use ",[944,2172,2173],{},"$.extend"," to perform a deep copy of any object that I ",[944,2176,1691],{}," from a model using the following syntax. Remember to pass ",[944,2179,1146],{},", so that it performs a deep copy of the object.",[949,2182,2184],{"className":951,"code":2183,"language":953,"meta":954,"style":954},"var address = $.extend(true, {}, person.address);\n",[944,2185,2186],{"__ignoreMap":954},[958,2187,2188,2190,2192,2194,2196,2198,2200,2202],{"class":960,"line":961},[958,2189,965],{"class":964},[958,2191,2042],{"class":968},[958,2193,972],{"class":964},[958,2195,1408],{"class":968},[958,2197,979],{"class":978},[958,2199,1143],{"class":968},[958,2201,1146],{"class":1022},[958,2203,2204],{"class":968},", {}, person.address);\n",[934,2206,2207,2208,2211],{},"We now have an exact copy of the ",[944,2209,2210],{},"address"," object, and we can modify it to our heart’s content without worrying about modifying the actual model. You should be aware that this pattern works for the above example because all of the members of the address object are immutable(numbers, strings, etc.), and that while the above example works you should use caution when deep copying objects that contain objects. You should also know that there is a small performance hit from performing a deep copy, but I have never seen this cause noticeable problems. However, if you’re deep copying massive objects or thousands of objects all at once, you’ll likely want to do some performance profiling. This leads us directly to the next pattern.",[924,2213,2215],{"id":2214},"store-data-not-persisted-by-the-server","Store Data Not Persisted By The Server",[934,2217,2218,2219,2222],{},"Although Backbone.js prescribes that models and collections map to representational state transfer (or REST-ful) endpoints, you will sometimes find that you want to store data in your models or collections that are not persisted on the server. Many other articles about Backbone.js, such as *Backbone.js Tips: Lessons From the Trenches” by Prateek Dayal of SupportBee, describe this pattern. Let’s look at a quick example to help explain where this might come in handy. Suppose you have a ",[944,2220,2221],{},"ul"," list.",[949,2224,2227],{"className":2225,"code":2226,"language":383,"meta":954,"style":954},"language-html shiki shiki-themes github-light github-dark","\u003Cul>\n  \u003Cli>\u003Ca href=\"#\" data-id=\"1\">One\u003C\u002Fa>\u003C\u002Fli>\n  \u003Cli>\u003Ca href=\"#\" data-id=\"2\">Two\u003C\u002Fa>\u003C\u002Fli>\n  . . .\n  \u003Cli>\u003Ca href=\"#\" data-id=\"n\">n\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n",[944,2228,2229,2240,2282,2316,2321,2355],{"__ignoreMap":954},[958,2230,2231,2234,2237],{"class":960,"line":961},[958,2232,2233],{"class":968},"\u003C",[958,2235,2221],{"class":2236},"s9eBZ",[958,2238,2239],{"class":968},">\n",[958,2241,2242,2245,2248,2251,2254,2257,2259,2262,2265,2267,2270,2273,2275,2278,2280],{"class":960,"line":985},[958,2243,2244],{"class":968},"  \u003C",[958,2246,2247],{"class":2236},"li",[958,2249,2250],{"class":968},">\u003C",[958,2252,2253],{"class":2236},"a",[958,2255,2256],{"class":978}," href",[958,2258,972],{"class":968},[958,2260,2261],{"class":997},"\"#\"",[958,2263,2264],{"class":978}," data-id",[958,2266,972],{"class":968},[958,2268,2269],{"class":997},"\"1\"",[958,2271,2272],{"class":968},">One\u003C\u002F",[958,2274,2253],{"class":2236},[958,2276,2277],{"class":968},">\u003C\u002F",[958,2279,2247],{"class":2236},[958,2281,2239],{"class":968},[958,2283,2284,2286,2288,2290,2292,2294,2296,2298,2300,2302,2305,2308,2310,2312,2314],{"class":960,"line":991},[958,2285,2244],{"class":968},[958,2287,2247],{"class":2236},[958,2289,2250],{"class":968},[958,2291,2253],{"class":2236},[958,2293,2256],{"class":978},[958,2295,972],{"class":968},[958,2297,2261],{"class":997},[958,2299,2264],{"class":978},[958,2301,972],{"class":968},[958,2303,2304],{"class":997},"\"2\"",[958,2306,2307],{"class":968},">Two\u003C\u002F",[958,2309,2253],{"class":2236},[958,2311,2277],{"class":968},[958,2313,2247],{"class":2236},[958,2315,2239],{"class":968},[958,2317,2318],{"class":960,"line":1004},[958,2319,2320],{"class":968},"  . . .\n",[958,2322,2323,2325,2327,2329,2331,2333,2335,2337,2339,2341,2344,2347,2349,2351,2353],{"class":960,"line":1010},[958,2324,2244],{"class":968},[958,2326,2247],{"class":2236},[958,2328,2250],{"class":968},[958,2330,2253],{"class":2236},[958,2332,2256],{"class":978},[958,2334,972],{"class":968},[958,2336,2261],{"class":997},[958,2338,2264],{"class":978},[958,2340,972],{"class":968},[958,2342,2343],{"class":997},"\"n\"",[958,2345,2346],{"class":968},">n\u003C\u002F",[958,2348,2253],{"class":2236},[958,2350,2277],{"class":968},[958,2352,2247],{"class":2236},[958,2354,2239],{"class":968},[958,2356,2357,2360,2362],{"class":960,"line":1016},[958,2358,2359],{"class":968},"\u003C\u002F",[958,2361,2221],{"class":2236},[958,2363,2239],{"class":968},[934,2365,2366,2367,2370,2371,2374],{},"Where ",[944,2368,2369],{},"n"," is 200 and when the user clicks on one of the items, that item becomes selected and is visualized to the user as the chosen item by a ",[944,2372,2373],{},"selected","class being added. One approach to this would be the following:",[949,2376,2378],{"className":951,"code":2377,"language":953,"meta":954,"style":954},"var Model = Backbone.Model.extend({\n  defaults: {\n    items: [\n      {\n        name: 'One',\n        id: 1,\n      },\n      {\n        name: 'Two',\n        id: 2,\n      },\n      {\n        name: 'Three',\n        id: 3,\n      },\n    ],\n  },\n});\n\nvar View = Backbone.View.extend({\n  template: _.template($('#list-template').html()),\n\n  events: {\n    '#items li a': 'setSelectedItem',\n  },\n\n  render: function () {\n    $(this.el).html(this.template(this.model.toJSON()));\n  },\n\n  setSelectedItem: function (event) {\n    var selectedItem = $(event.currentTarget);\n    \u002F\u002F Set all of the items to not have the selected class\n    $('#items li a').removeClass('selected');\n    selectedItem.addClass('selected');\n    return false;\n  },\n});\n",[944,2379,2380,2395,2399,2404,2408,2417,2427,2431,2435,2444,2453,2457,2461,2470,2479,2483,2487,2491,2495,2499,2515,2541,2545,2550,2562,2566,2570,2581,2616,2620,2624,2640,2656,2661,2682,2696,2706,2710],{"__ignoreMap":954},[958,2381,2382,2384,2387,2389,2391,2393],{"class":960,"line":961},[958,2383,965],{"class":964},[958,2385,2386],{"class":968}," Model ",[958,2388,972],{"class":964},[958,2390,975],{"class":968},[958,2392,979],{"class":978},[958,2394,982],{"class":968},[958,2396,2397],{"class":960,"line":985},[958,2398,988],{"class":968},[958,2400,2401],{"class":960,"line":991},[958,2402,2403],{"class":968},"    items: [\n",[958,2405,2406],{"class":960,"line":1004},[958,2407,1281],{"class":968},[958,2409,2410,2412,2415],{"class":960,"line":1010},[958,2411,1286],{"class":968},[958,2413,2414],{"class":997},"'One'",[958,2416,1026],{"class":968},[958,2418,2419,2422,2425],{"class":960,"line":1016},[958,2420,2421],{"class":968},"        id: ",[958,2423,2424],{"class":1022},"1",[958,2426,1026],{"class":968},[958,2428,2429],{"class":960,"line":1029},[958,2430,1043],{"class":968},[958,2432,2433],{"class":960,"line":1040},[958,2434,1281],{"class":968},[958,2436,2437,2439,2442],{"class":960,"line":1046},[958,2438,1286],{"class":968},[958,2440,2441],{"class":997},"'Two'",[958,2443,1026],{"class":968},[958,2445,2446,2448,2451],{"class":960,"line":1052},[958,2447,2421],{"class":968},[958,2449,2450],{"class":1022},"2",[958,2452,1026],{"class":968},[958,2454,2455],{"class":960,"line":1062},[958,2456,1043],{"class":968},[958,2458,2459],{"class":960,"line":1072},[958,2460,1281],{"class":968},[958,2462,2463,2465,2468],{"class":960,"line":1077},[958,2464,1286],{"class":968},[958,2466,2467],{"class":997},"'Three'",[958,2469,1026],{"class":968},[958,2471,2472,2474,2477],{"class":960,"line":1083},[958,2473,2421],{"class":968},[958,2475,2476],{"class":1022},"3",[958,2478,1026],{"class":968},[958,2480,2481],{"class":960,"line":1093},[958,2482,1043],{"class":968},[958,2484,2485],{"class":960,"line":1102},[958,2486,1381],{"class":968},[958,2488,2489],{"class":960,"line":1107},[958,2490,1231],{"class":968},[958,2492,2493],{"class":960,"line":1113},[958,2494,1237],{"class":968},[958,2496,2497],{"class":960,"line":1120},[958,2498,1117],{"emptyLinePlaceholder":1116},[958,2500,2501,2503,2506,2508,2511,2513],{"class":960,"line":1135},[958,2502,965],{"class":964},[958,2504,2505],{"class":968}," View ",[958,2507,972],{"class":964},[958,2509,2510],{"class":968}," Backbone.View.",[958,2512,979],{"class":978},[958,2514,982],{"class":968},[958,2516,2517,2520,2523,2525,2528,2530,2533,2536,2538],{"class":960,"line":1169},[958,2518,2519],{"class":968},"  template: _.",[958,2521,2522],{"class":978},"template",[958,2524,1143],{"class":968},[958,2526,2527],{"class":978},"$",[958,2529,1143],{"class":968},[958,2531,2532],{"class":997},"'#list-template'",[958,2534,2535],{"class":968},").",[958,2537,383],{"class":978},[958,2539,2540],{"class":968},"()),\n",[958,2542,2543],{"class":960,"line":1174},[958,2544,1117],{"emptyLinePlaceholder":1116},[958,2546,2547],{"class":960,"line":1179},[958,2548,2549],{"class":968},"  events: {\n",[958,2551,2552,2555,2557,2560],{"class":960,"line":1199},[958,2553,2554],{"class":997},"    '#items li a'",[958,2556,1126],{"class":968},[958,2558,2559],{"class":997},"'setSelectedItem'",[958,2561,1026],{"class":968},[958,2563,2564],{"class":960,"line":1223},[958,2565,1231],{"class":968},[958,2567,2568],{"class":960,"line":1228},[958,2569,1117],{"emptyLinePlaceholder":1116},[958,2571,2572,2575,2577,2579],{"class":960,"line":1234},[958,2573,2574],{"class":978},"  render",[958,2576,1126],{"class":968},[958,2578,1129],{"class":964},[958,2580,1132],{"class":968},[958,2582,2583,2586,2588,2590,2593,2595,2597,2599,2601,2603,2605,2607,2610,2613],{"class":960,"line":1472},[958,2584,2585],{"class":978},"    $",[958,2587,1143],{"class":968},[958,2589,1152],{"class":1022},[958,2591,2592],{"class":968},".el).",[958,2594,383],{"class":978},[958,2596,1143],{"class":968},[958,2598,1152],{"class":1022},[958,2600,1155],{"class":968},[958,2602,2522],{"class":978},[958,2604,1143],{"class":968},[958,2606,1152],{"class":1022},[958,2608,2609],{"class":968},".model.",[958,2611,2612],{"class":978},"toJSON",[958,2614,2615],{"class":968},"()));\n",[958,2617,2618],{"class":960,"line":1483},[958,2619,1231],{"class":968},[958,2621,2622],{"class":960,"line":1489},[958,2623,1117],{"emptyLinePlaceholder":1116},[958,2625,2626,2629,2631,2633,2635,2638],{"class":960,"line":1495},[958,2627,2628],{"class":978},"  setSelectedItem",[958,2630,1126],{"class":968},[958,2632,1129],{"class":964},[958,2634,1189],{"class":968},[958,2636,2637],{"class":1192},"event",[958,2639,1196],{"class":968},[958,2641,2642,2645,2648,2650,2653],{"class":960,"line":1501},[958,2643,2644],{"class":964},"    var",[958,2646,2647],{"class":968}," selectedItem ",[958,2649,972],{"class":964},[958,2651,2652],{"class":978}," $",[958,2654,2655],{"class":968},"(event.currentTarget);\n",[958,2657,2658],{"class":960,"line":1507},[958,2659,2660],{"class":1448},"    \u002F\u002F Set all of the items to not have the selected class\n",[958,2662,2663,2665,2667,2670,2672,2675,2677,2680],{"class":960,"line":1512},[958,2664,2585],{"class":978},[958,2666,1143],{"class":968},[958,2668,2669],{"class":997},"'#items li a'",[958,2671,2535],{"class":968},[958,2673,2674],{"class":978},"removeClass",[958,2676,1143],{"class":968},[958,2678,2679],{"class":997},"'selected'",[958,2681,2057],{"class":968},[958,2683,2684,2687,2690,2692,2694],{"class":960,"line":1517},[958,2685,2686],{"class":968},"    selectedItem.",[958,2688,2689],{"class":978},"addClass",[958,2691,1143],{"class":968},[958,2693,2679],{"class":997},[958,2695,2057],{"class":968},[958,2697,2698,2701,2704],{"class":960,"line":1532},[958,2699,2700],{"class":964},"    return",[958,2702,2703],{"class":1022}," false",[958,2705,1951],{"class":968},[958,2707,2708],{"class":960,"line":1551},[958,2709,1231],{"class":968},[958,2711,2712],{"class":960,"line":1556},[958,2713,1237],{"class":968},[949,2715,2717],{"className":2225,"code":2716,"language":383,"meta":954,"style":954},"\u003Cscript id=\"list-template\" type=\"template\">\n  \u003Cul id=\"items\">\n          \u003C% for(i = items.length - 1; i >= 0; i--) { %>\n    \u003Cli>\n                  \u003Ca href=\"#\" data-id=\"\u003C%= item[i].id %>\">\u003C%= item[i].name %>\u003C\u002Fa>\u003C\u002Fli>\n  \u003C% } %>\u003C\u002Ful>\n\u003C\u002Fscript>\n",[944,2718,2719,2744,2749,2754,2759,2764,2769],{"__ignoreMap":954},[958,2720,2721,2723,2726,2729,2731,2734,2737,2739,2742],{"class":960,"line":961},[958,2722,2233],{"class":968},[958,2724,2725],{"class":2236},"script",[958,2727,2728],{"class":978}," id",[958,2730,972],{"class":968},[958,2732,2733],{"class":997},"\"list-template\"",[958,2735,2736],{"class":978}," type",[958,2738,972],{"class":968},[958,2740,2741],{"class":997},"\"template\"",[958,2743,2239],{"class":968},[958,2745,2746],{"class":960,"line":985},[958,2747,2748],{"class":968},"  \u003Cul id=\"items\">\n",[958,2750,2751],{"class":960,"line":991},[958,2752,2753],{"class":968},"          \u003C% for(i = items.length - 1; i >= 0; i--) { %>\n",[958,2755,2756],{"class":960,"line":1004},[958,2757,2758],{"class":968},"    \u003Cli>\n",[958,2760,2761],{"class":960,"line":1010},[958,2762,2763],{"class":968},"                  \u003Ca href=\"#\" data-id=\"\u003C%= item[i].id %>\">\u003C%= item[i].name %>\u003C\u002Fa>\u003C\u002Fli>\n",[958,2765,2766],{"class":960,"line":1016},[958,2767,2768],{"class":968},"  \u003C% } %>\u003C\u002Ful>\n",[958,2770,2771,2773,2775],{"class":960,"line":1029},[958,2772,2359],{"class":968},[958,2774,2725],{"class":2236},[958,2776,2239],{"class":968},[934,2778,2779],{},"Now let’s say we want to figure out which item has been selected. One way would be to traverse the list. But if the list is really long, this could become quite an expensive task. Therefore, let’s also store which item is selected when the user clicks on a list item.",[949,2781,2783],{"className":951,"code":2782,"language":953,"meta":954,"style":954},"var View = Backbone.View.extend({\n    initialize: function(options) {\n        \u002F\u002F Re-render when the model changes\n        this.model.on('change:items', this.render, this);\n    },\n\n    template: _.template($('#list-template').html()),\n\n    events: {\n        \"#items li a\": \"setSelectedItem\"\n    },\n\n    render: function() {\n        $(this.el).html(this.template(this.model.toJSON()));\n    },\n\n    setSelectedItem: function(event) {\n        var selectedItem = $(event.currentTarget);\n        \u002F\u002F Set all of the items to not have the selected class\n        $('#items li a').removeClass('selected');\n        selectedItem.addClass('selected');\n        \u002F\u002F Store a reference to what item was selected\n        this.selectedItemId = selectedItem.data('id'));\n        return false;\n    }\n});\n",[944,2784,2785,2799,2815,2820,2846,2850,2854,2875,2879,2884,2894,2898,2902,2914,2945,2949,2953,2968,2981,2986,3004,3017,3022,3044,3053,3057],{"__ignoreMap":954},[958,2786,2787,2789,2791,2793,2795,2797],{"class":960,"line":961},[958,2788,965],{"class":964},[958,2790,2505],{"class":968},[958,2792,972],{"class":964},[958,2794,2510],{"class":968},[958,2796,979],{"class":978},[958,2798,982],{"class":968},[958,2800,2801,2804,2806,2808,2810,2813],{"class":960,"line":985},[958,2802,2803],{"class":978},"    initialize",[958,2805,1126],{"class":968},[958,2807,1129],{"class":964},[958,2809,1143],{"class":968},[958,2811,2812],{"class":1192},"options",[958,2814,1196],{"class":968},[958,2816,2817],{"class":960,"line":991},[958,2818,2819],{"class":1448},"        \u002F\u002F Re-render when the model changes\n",[958,2821,2822,2825,2827,2830,2832,2835,2837,2839,2842,2844],{"class":960,"line":1004},[958,2823,2824],{"class":1022},"        this",[958,2826,2609],{"class":968},[958,2828,2829],{"class":978},"on",[958,2831,1143],{"class":968},[958,2833,2834],{"class":997},"'change:items'",[958,2836,1866],{"class":968},[958,2838,1152],{"class":1022},[958,2840,2841],{"class":968},".render, ",[958,2843,1152],{"class":1022},[958,2845,2057],{"class":968},[958,2847,2848],{"class":960,"line":1010},[958,2849,1110],{"class":968},[958,2851,2852],{"class":960,"line":1016},[958,2853,1117],{"emptyLinePlaceholder":1116},[958,2855,2856,2859,2861,2863,2865,2867,2869,2871,2873],{"class":960,"line":1029},[958,2857,2858],{"class":968},"    template: _.",[958,2860,2522],{"class":978},[958,2862,1143],{"class":968},[958,2864,2527],{"class":978},[958,2866,1143],{"class":968},[958,2868,2532],{"class":997},[958,2870,2535],{"class":968},[958,2872,383],{"class":978},[958,2874,2540],{"class":968},[958,2876,2877],{"class":960,"line":1040},[958,2878,1117],{"emptyLinePlaceholder":1116},[958,2880,2881],{"class":960,"line":1046},[958,2882,2883],{"class":968},"    events: {\n",[958,2885,2886,2889,2891],{"class":960,"line":1052},[958,2887,2888],{"class":997},"        \"#items li a\"",[958,2890,1126],{"class":968},[958,2892,2893],{"class":997},"\"setSelectedItem\"\n",[958,2895,2896],{"class":960,"line":1062},[958,2897,1110],{"class":968},[958,2899,2900],{"class":960,"line":1072},[958,2901,1117],{"emptyLinePlaceholder":1116},[958,2903,2904,2907,2909,2911],{"class":960,"line":1077},[958,2905,2906],{"class":978},"    render",[958,2908,1126],{"class":968},[958,2910,1129],{"class":964},[958,2912,2913],{"class":968},"() {\n",[958,2915,2916,2919,2921,2923,2925,2927,2929,2931,2933,2935,2937,2939,2941,2943],{"class":960,"line":1083},[958,2917,2918],{"class":978},"        $",[958,2920,1143],{"class":968},[958,2922,1152],{"class":1022},[958,2924,2592],{"class":968},[958,2926,383],{"class":978},[958,2928,1143],{"class":968},[958,2930,1152],{"class":1022},[958,2932,1155],{"class":968},[958,2934,2522],{"class":978},[958,2936,1143],{"class":968},[958,2938,1152],{"class":1022},[958,2940,2609],{"class":968},[958,2942,2612],{"class":978},[958,2944,2615],{"class":968},[958,2946,2947],{"class":960,"line":1093},[958,2948,1110],{"class":968},[958,2950,2951],{"class":960,"line":1102},[958,2952,1117],{"emptyLinePlaceholder":1116},[958,2954,2955,2958,2960,2962,2964,2966],{"class":960,"line":1107},[958,2956,2957],{"class":978},"    setSelectedItem",[958,2959,1126],{"class":968},[958,2961,1129],{"class":964},[958,2963,1143],{"class":968},[958,2965,2637],{"class":1192},[958,2967,1196],{"class":968},[958,2969,2970,2973,2975,2977,2979],{"class":960,"line":1113},[958,2971,2972],{"class":964},"        var",[958,2974,2647],{"class":968},[958,2976,972],{"class":964},[958,2978,2652],{"class":978},[958,2980,2655],{"class":968},[958,2982,2983],{"class":960,"line":1120},[958,2984,2985],{"class":1448},"        \u002F\u002F Set all of the items to not have the selected class\n",[958,2987,2988,2990,2992,2994,2996,2998,3000,3002],{"class":960,"line":1135},[958,2989,2918],{"class":978},[958,2991,1143],{"class":968},[958,2993,2669],{"class":997},[958,2995,2535],{"class":968},[958,2997,2674],{"class":978},[958,2999,1143],{"class":968},[958,3001,2679],{"class":997},[958,3003,2057],{"class":968},[958,3005,3006,3009,3011,3013,3015],{"class":960,"line":1169},[958,3007,3008],{"class":968},"        selectedItem.",[958,3010,2689],{"class":978},[958,3012,1143],{"class":968},[958,3014,2679],{"class":997},[958,3016,2057],{"class":968},[958,3018,3019],{"class":960,"line":1174},[958,3020,3021],{"class":1448},"        \u002F\u002F Store a reference to what item was selected\n",[958,3023,3024,3026,3029,3031,3034,3037,3039,3042],{"class":960,"line":1179},[958,3025,2824],{"class":1022},[958,3027,3028],{"class":968},".selectedItemId ",[958,3030,972],{"class":964},[958,3032,3033],{"class":968}," selectedItem.",[958,3035,3036],{"class":978},"data",[958,3038,1143],{"class":968},[958,3040,3041],{"class":997},"'id'",[958,3043,1166],{"class":968},[958,3045,3046,3049,3051],{"class":960,"line":1199},[958,3047,3048],{"class":964},"        return",[958,3050,2703],{"class":1022},[958,3052,1951],{"class":968},[958,3054,3055],{"class":960,"line":1223},[958,3056,2023],{"class":968},[958,3058,3059],{"class":960,"line":1228},[958,3060,1237],{"class":968},[934,3062,3063],{},"Now we can now easily determine which item has been selected, and we don’t have to traverse the Document Object Model (DOM). This pattern is extremely useful for storing extraneous data that you might want to keep track of; keep in mind also that you can create models and collections that don’t necessarily have endpoints associated with them to store extraneous view data.",[934,3065,3066],{},"The downsides to this pattern are that if you store extraneous data in your models or collections, they won’t follow a RESTful architecture since they won’t map perfectly to a Web resource; also, this pattern can cause a bit of bloat in your objects; and it can cause a bit of pain when saving your models if your endpoint strictly accepts only the JSON it expects.",[934,3068,3069],{},"You may be asking yourself, *How do I determine if I should put the extra data in the view or the model?”. If the extra attributes you’re adding are centred around rendering, such as the height of a container, they should probably be added to the view. If the attributes have anything to do with the underlying data model, then you may want to push that into the model. For example, if the above example were more fleshed out and for some reason I only wanted users to be able to select a specific range of items from the list of items returned by the model, I would likely push that logic into the model. In short, as most things go, it depends on the situation. You can argue for keeping your models truly faithful to REST and you can argue that you should keep your views as dumb as possible and push as much logic into your models.",[924,3071,3073],{"id":3072},"render-parts-of-views-instead-of-entire-views","Render Parts Of Views Instead Of Entire Views",[934,3075,3076],{},"When you first begin developing Backbone.js applications, your views will typically be structured something like this:",[949,3078,3080],{"className":951,"code":3079,"language":953,"meta":954,"style":954},"var View = Backbone.View.extend({\n    initialize: function(options) {\n        this.model.on('change', this.render, this);\n    },\n\n    template: _.template($(‘#template’).html()),\n\n    render: function() {\n        this.$el.html(template(this.model.toJSON());\n        $(‘#a’, this.$el).html(this.model.get(‘a’));\n        $(‘#b’, this.$el).html(this.model.get(‘b’));\n    }\n});\n",[944,3081,3082,3096,3110,3133,3137,3141,3158,3162,3172,3196,3221,3245,3249],{"__ignoreMap":954},[958,3083,3084,3086,3088,3090,3092,3094],{"class":960,"line":961},[958,3085,965],{"class":964},[958,3087,2505],{"class":968},[958,3089,972],{"class":964},[958,3091,2510],{"class":968},[958,3093,979],{"class":978},[958,3095,982],{"class":968},[958,3097,3098,3100,3102,3104,3106,3108],{"class":960,"line":985},[958,3099,2803],{"class":978},[958,3101,1126],{"class":968},[958,3103,1129],{"class":964},[958,3105,1143],{"class":968},[958,3107,2812],{"class":1192},[958,3109,1196],{"class":968},[958,3111,3112,3114,3116,3118,3120,3123,3125,3127,3129,3131],{"class":960,"line":991},[958,3113,2824],{"class":1022},[958,3115,2609],{"class":968},[958,3117,2829],{"class":978},[958,3119,1143],{"class":968},[958,3121,3122],{"class":997},"'change'",[958,3124,1866],{"class":968},[958,3126,1152],{"class":1022},[958,3128,2841],{"class":968},[958,3130,1152],{"class":1022},[958,3132,2057],{"class":968},[958,3134,3135],{"class":960,"line":1004},[958,3136,1110],{"class":968},[958,3138,3139],{"class":960,"line":1010},[958,3140,1117],{"emptyLinePlaceholder":1116},[958,3142,3143,3145,3147,3149,3151,3154,3156],{"class":960,"line":1016},[958,3144,2858],{"class":968},[958,3146,2522],{"class":978},[958,3148,1143],{"class":968},[958,3150,2527],{"class":978},[958,3152,3153],{"class":968},"(‘#template’).",[958,3155,383],{"class":978},[958,3157,2540],{"class":968},[958,3159,3160],{"class":960,"line":1029},[958,3161,1117],{"emptyLinePlaceholder":1116},[958,3163,3164,3166,3168,3170],{"class":960,"line":1040},[958,3165,2906],{"class":978},[958,3167,1126],{"class":968},[958,3169,1129],{"class":964},[958,3171,2913],{"class":968},[958,3173,3174,3176,3179,3181,3183,3185,3187,3189,3191,3193],{"class":960,"line":1046},[958,3175,2824],{"class":1022},[958,3177,3178],{"class":968},".$el.",[958,3180,383],{"class":978},[958,3182,1143],{"class":968},[958,3184,2522],{"class":978},[958,3186,1143],{"class":968},[958,3188,1152],{"class":1022},[958,3190,2609],{"class":968},[958,3192,2612],{"class":978},[958,3194,3195],{"class":968},"());\n",[958,3197,3198,3200,3203,3205,3208,3210,3212,3214,3216,3218],{"class":960,"line":1052},[958,3199,2918],{"class":978},[958,3201,3202],{"class":968},"(‘#a’, ",[958,3204,1152],{"class":1022},[958,3206,3207],{"class":968},".$el).",[958,3209,383],{"class":978},[958,3211,1143],{"class":968},[958,3213,1152],{"class":1022},[958,3215,2609],{"class":968},[958,3217,1158],{"class":978},[958,3219,3220],{"class":968},"(‘a’));\n",[958,3222,3223,3225,3228,3230,3232,3234,3236,3238,3240,3242],{"class":960,"line":1062},[958,3224,2918],{"class":978},[958,3226,3227],{"class":968},"(‘#b’, ",[958,3229,1152],{"class":1022},[958,3231,3207],{"class":968},[958,3233,383],{"class":978},[958,3235,1143],{"class":968},[958,3237,1152],{"class":1022},[958,3239,2609],{"class":968},[958,3241,1158],{"class":978},[958,3243,3244],{"class":968},"(‘b’));\n",[958,3246,3247],{"class":960,"line":1072},[958,3248,2023],{"class":968},[958,3250,3251],{"class":960,"line":1077},[958,3252,1237],{"class":968},[934,3254,3255],{},"Here, any change to your model will trigger a complete re-rendering of the view. I was a practitioner of this pattern when I first began developing with Backbone.js. But as my view code grew in price, I quickly realized that this approach was not maintainable or optimal because the view was being completely re-rendered when any attribute of the model changed.",[934,3257,3258,3259,3263],{},"When I ran into this problem, I did a quick Google search to see what others had done and found Ian Storm Taylor’s blog post, *",[2253,3260,3262],{"href":3261},"http:\u002F\u002Fianstormtaylor.com\u002Fbreak-apart-your-backbonejs-render-methods\u002F","Break Apart Your Backbone.js Render Methods",",” in which he describes listening for individual attribute changes in the model and then re-rendering only the part of the view corresponding to the changed attribute. Taylor also describes returning a reference to the object so that the individual rendering functions can be easily chained together. The example above now transforms into something much more maintainable and performant because we are only updating portions of the view that correspond to the model attributes that have changed.",[949,3265,3267],{"className":951,"code":3266,"language":953,"meta":954,"style":954},"var View = Backbone.View.extend({\n    initialize: function(options) {\n        this.model.on('change:a', this.renderA, this);\n        this.model.on('change:b', this.renderB, this);\n    },\n\n    renderA: function() {\n        $(‘#a’, this.$el).html(this.model.get(‘a’));\n        return this;\n    },\n\n    renderB: function() {\n        $(‘#b’, this.$el).html(this.model.get(‘b’));\n        return this;\n    },\n\n    render: function() {\n        this\n            .renderA()\n            .renderB();\n    }\n});\n",[944,3268,3269,3283,3297,3321,3345,3349,3353,3364,3386,3395,3399,3403,3414,3436,3444,3448,3452,3462,3467,3478,3488,3492],{"__ignoreMap":954},[958,3270,3271,3273,3275,3277,3279,3281],{"class":960,"line":961},[958,3272,965],{"class":964},[958,3274,2505],{"class":968},[958,3276,972],{"class":964},[958,3278,2510],{"class":968},[958,3280,979],{"class":978},[958,3282,982],{"class":968},[958,3284,3285,3287,3289,3291,3293,3295],{"class":960,"line":985},[958,3286,2803],{"class":978},[958,3288,1126],{"class":968},[958,3290,1129],{"class":964},[958,3292,1143],{"class":968},[958,3294,2812],{"class":1192},[958,3296,1196],{"class":968},[958,3298,3299,3301,3303,3305,3307,3310,3312,3314,3317,3319],{"class":960,"line":991},[958,3300,2824],{"class":1022},[958,3302,2609],{"class":968},[958,3304,2829],{"class":978},[958,3306,1143],{"class":968},[958,3308,3309],{"class":997},"'change:a'",[958,3311,1866],{"class":968},[958,3313,1152],{"class":1022},[958,3315,3316],{"class":968},".renderA, ",[958,3318,1152],{"class":1022},[958,3320,2057],{"class":968},[958,3322,3323,3325,3327,3329,3331,3334,3336,3338,3341,3343],{"class":960,"line":1004},[958,3324,2824],{"class":1022},[958,3326,2609],{"class":968},[958,3328,2829],{"class":978},[958,3330,1143],{"class":968},[958,3332,3333],{"class":997},"'change:b'",[958,3335,1866],{"class":968},[958,3337,1152],{"class":1022},[958,3339,3340],{"class":968},".renderB, ",[958,3342,1152],{"class":1022},[958,3344,2057],{"class":968},[958,3346,3347],{"class":960,"line":1010},[958,3348,1110],{"class":968},[958,3350,3351],{"class":960,"line":1016},[958,3352,1117],{"emptyLinePlaceholder":1116},[958,3354,3355,3358,3360,3362],{"class":960,"line":1029},[958,3356,3357],{"class":978},"    renderA",[958,3359,1126],{"class":968},[958,3361,1129],{"class":964},[958,3363,2913],{"class":968},[958,3365,3366,3368,3370,3372,3374,3376,3378,3380,3382,3384],{"class":960,"line":1040},[958,3367,2918],{"class":978},[958,3369,3202],{"class":968},[958,3371,1152],{"class":1022},[958,3373,3207],{"class":968},[958,3375,383],{"class":978},[958,3377,1143],{"class":968},[958,3379,1152],{"class":1022},[958,3381,2609],{"class":968},[958,3383,1158],{"class":978},[958,3385,3220],{"class":968},[958,3387,3388,3390,3393],{"class":960,"line":1046},[958,3389,3048],{"class":964},[958,3391,3392],{"class":1022}," this",[958,3394,1951],{"class":968},[958,3396,3397],{"class":960,"line":1052},[958,3398,1110],{"class":968},[958,3400,3401],{"class":960,"line":1062},[958,3402,1117],{"emptyLinePlaceholder":1116},[958,3404,3405,3408,3410,3412],{"class":960,"line":1072},[958,3406,3407],{"class":978},"    renderB",[958,3409,1126],{"class":968},[958,3411,1129],{"class":964},[958,3413,2913],{"class":968},[958,3415,3416,3418,3420,3422,3424,3426,3428,3430,3432,3434],{"class":960,"line":1077},[958,3417,2918],{"class":978},[958,3419,3227],{"class":968},[958,3421,1152],{"class":1022},[958,3423,3207],{"class":968},[958,3425,383],{"class":978},[958,3427,1143],{"class":968},[958,3429,1152],{"class":1022},[958,3431,2609],{"class":968},[958,3433,1158],{"class":978},[958,3435,3244],{"class":968},[958,3437,3438,3440,3442],{"class":960,"line":1083},[958,3439,3048],{"class":964},[958,3441,3392],{"class":1022},[958,3443,1951],{"class":968},[958,3445,3446],{"class":960,"line":1093},[958,3447,1110],{"class":968},[958,3449,3450],{"class":960,"line":1102},[958,3451,1117],{"emptyLinePlaceholder":1116},[958,3453,3454,3456,3458,3460],{"class":960,"line":1107},[958,3455,2906],{"class":978},[958,3457,1126],{"class":968},[958,3459,1129],{"class":964},[958,3461,2913],{"class":968},[958,3463,3464],{"class":960,"line":1113},[958,3465,3466],{"class":1022},"        this\n",[958,3468,3469,3472,3475],{"class":960,"line":1120},[958,3470,3471],{"class":968},"            .",[958,3473,3474],{"class":978},"renderA",[958,3476,3477],{"class":968},"()\n",[958,3479,3480,3482,3485],{"class":960,"line":1135},[958,3481,3471],{"class":968},[958,3483,3484],{"class":978},"renderB",[958,3486,3487],{"class":968},"();\n",[958,3489,3490],{"class":960,"line":1169},[958,3491,2023],{"class":968},[958,3493,3494],{"class":960,"line":1174},[958,3495,1237],{"class":968},[934,3497,3498,3499,3505,3506,3511],{},"I should mention that many plugins, such as ",[2253,3500,3504],{"href":3501,"rel":3502},"http:\u002F\u002Fnytimes.github.io\u002Fbackbone.stickit\u002F",[3503],"nofollow","Backbone.StickIt"," and ",[2253,3507,3510],{"href":3508,"rel":3509},"https:\u002F\u002Fgithub.com\u002Ftheironcook\u002FBackbone.ModelBinder",[3503],"Backbone.ModelBinder\u003C",", provide key-value bindings between model attributes and view elements, which can save you from a lot of boilerplate code. So, check them out if you have complex form fields.",[929,3513,3515],{"id":3514},"keep-models-agnostic-to-views","Keep Models Agnostic To Views",[934,3517,3518,3519,3524,3525,3505,3530,3535],{},"As Jeremy Ashkenas points out in one of Backbone.js ",[2253,3520,3523],{"href":3521,"rel":3522},"https:\u002F\u002Fgithub.com\u002Fdocumentcloud\u002Fbackbone\u002Fissues\u002F21",[3503],"GitHub issues",", Backbone.js doesn’t enforce any real separation of concerns between the data and view layer, except that models are not created with a reference to their view. Because Backbone.js doesn’t enforce a separation of concerns, should you? I and many other Backbone.js developers, such as ",[2253,3526,3529],{"href":3527,"rel":3528},"http:\u002F\u002Fozkatz.github.io\u002Favoiding-common-backbonejs-pitfalls.html",[3503],"Oz Katz",[2253,3531,3534],{"href":3532,"rel":3533},"https:\u002F\u002Fsupportbee.com\u002Fdevblog\u002F2011\u002F07\u002F29\u002Fbackbone-js-tips-lessons-from-the-trenches\u002F",[3503],"Dayal",", believe the answer is overwhelmingly yes: Models and collections, the data layer, should be entirely agnostic of the views that are bound to them, keeping a clear separation of concerns. If you don’t follow a separation of concerns, your codebase could quickly turn into spaghetti code, and no one likes spaghetti code.",[934,3537,3538],{},"Keeping your data layer completely agnostic to the view layer allows for a more modular, reusable and maintainable codebase. You can easily reuse and extend models and collections throughout your application without concern for the views that are tying into them. Following this pattern enables developers who are new to your project to quickly dive into the code base, because they will know exactly where rendering takes place and where all of the business logic of your application should live.",[934,3540,3541,3542,3547],{},"This pattern also enforces the ",[2253,3543,3546],{"href":3544,"rel":3545},"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSingle_responsibility_principle",[3503],"single responsibility principle",", which dictates that each class should have a single responsibility, and its responsibility should be encapsulated in the class since your models and collections should handle data and your views should handle rendering.",[929,3549,3551],{"id":3550},"parameter-mapping-in-routers","Parameter Mapping In Routers",[934,3553,3554,3555,3505,3558,3561],{},"The best way to demonstrate how this pattern came about is through an example. Let’s say you have some sort of search page, and that the search page allows users to add two different filter types, ",[944,3556,3557],{},"foo",[944,3559,3560],{},"bar",", each of which has a multitude of options. Therefore, your URL structure would start off looking something like this:",[949,3563,3565],{"className":951,"code":3564,"language":953,"meta":954,"style":954},"'search\u002F:foo';\n'search\u002F:bar';\n'search\u002F:foo\u002F:bar';\n",[944,3566,3567,3574,3581],{"__ignoreMap":954},[958,3568,3569,3572],{"class":960,"line":961},[958,3570,3571],{"class":997},"'search\u002F:foo'",[958,3573,1951],{"class":968},[958,3575,3576,3579],{"class":960,"line":985},[958,3577,3578],{"class":997},"'search\u002F:bar'",[958,3580,1951],{"class":968},[958,3582,3583,3586],{"class":960,"line":991},[958,3584,3585],{"class":997},"'search\u002F:foo\u002F:bar'",[958,3587,1951],{"class":968},[934,3589,3590,3591,3594,3595,1155],{},"Now, all of these routes use the same view and model, so you would ideally like them all to use the same function, ",[944,3592,3593],{},"search()",". However, if you examine Backbone.js, there isn’t any sort of parameter mapping; the parameters are just plopped into the function from left to right. So, for them all to use the same function, you would end up creating different functions to correctly map the parameters to ",[944,3596,3593],{},[949,3598,3600],{"className":951,"code":3599,"language":953,"meta":954,"style":954},"routes: {\n    'search\u002F:foo': 'searchFoo',\n    'search\u002F:bar': 'searchBar',\n    'search\u002F:foo\u002F:bar': 'search'\n},\n\nsearch: function(foo, bar) {\n},\n\n\u002F\u002F I know this function will actually still map correctly, but for explanatory purposes, it's left in.\nsearchFoo: function(foo) {\n    this.search(foo, undefined);\n},\n\nsearchBar: function(bar) {\n    this.search(undefined, bar);\n},\n",[944,3601,3602,3609,3621,3633,3643,3648,3652,3671,3675,3679,3684,3699,3716,3720,3724,3739,3754],{"__ignoreMap":954},[958,3603,3604,3607],{"class":960,"line":961},[958,3605,3606],{"class":978},"routes",[958,3608,1741],{"class":968},[958,3610,3611,3614,3616,3619],{"class":960,"line":985},[958,3612,3613],{"class":997},"    'search\u002F:foo'",[958,3615,1126],{"class":968},[958,3617,3618],{"class":997},"'searchFoo'",[958,3620,1026],{"class":968},[958,3622,3623,3626,3628,3631],{"class":960,"line":991},[958,3624,3625],{"class":997},"    'search\u002F:bar'",[958,3627,1126],{"class":968},[958,3629,3630],{"class":997},"'searchBar'",[958,3632,1026],{"class":968},[958,3634,3635,3638,3640],{"class":960,"line":1004},[958,3636,3637],{"class":997},"    'search\u002F:foo\u002F:bar'",[958,3639,1126],{"class":968},[958,3641,3642],{"class":997},"'search'\n",[958,3644,3645],{"class":960,"line":1010},[958,3646,3647],{"class":968},"},\n",[958,3649,3650],{"class":960,"line":1016},[958,3651,1117],{"emptyLinePlaceholder":1116},[958,3653,3654,3657,3659,3661,3663,3665,3667,3669],{"class":960,"line":1029},[958,3655,3656],{"class":978},"search",[958,3658,1126],{"class":968},[958,3660,1129],{"class":964},[958,3662,1143],{"class":968},[958,3664,3557],{"class":1192},[958,3666,1866],{"class":968},[958,3668,3560],{"class":1192},[958,3670,1196],{"class":968},[958,3672,3673],{"class":960,"line":1040},[958,3674,3647],{"class":968},[958,3676,3677],{"class":960,"line":1046},[958,3678,1117],{"emptyLinePlaceholder":1116},[958,3680,3681],{"class":960,"line":1052},[958,3682,3683],{"class":1448},"\u002F\u002F I know this function will actually still map correctly, but for explanatory purposes, it's left in.\n",[958,3685,3686,3689,3691,3693,3695,3697],{"class":960,"line":1062},[958,3687,3688],{"class":978},"searchFoo",[958,3690,1126],{"class":968},[958,3692,1129],{"class":964},[958,3694,1143],{"class":968},[958,3696,3557],{"class":1192},[958,3698,1196],{"class":968},[958,3700,3701,3704,3706,3708,3711,3714],{"class":960,"line":1072},[958,3702,3703],{"class":1022},"    this",[958,3705,1155],{"class":968},[958,3707,3656],{"class":978},[958,3709,3710],{"class":968},"(foo, ",[958,3712,3713],{"class":1022},"undefined",[958,3715,2057],{"class":968},[958,3717,3718],{"class":960,"line":1077},[958,3719,3647],{"class":968},[958,3721,3722],{"class":960,"line":1083},[958,3723,1117],{"emptyLinePlaceholder":1116},[958,3725,3726,3729,3731,3733,3735,3737],{"class":960,"line":1093},[958,3727,3728],{"class":978},"searchBar",[958,3730,1126],{"class":968},[958,3732,1129],{"class":964},[958,3734,1143],{"class":968},[958,3736,3560],{"class":1192},[958,3738,1196],{"class":968},[958,3740,3741,3743,3745,3747,3749,3751],{"class":960,"line":1102},[958,3742,3703],{"class":1022},[958,3744,1155],{"class":968},[958,3746,3656],{"class":978},[958,3748,1143],{"class":968},[958,3750,3713],{"class":1022},[958,3752,3753],{"class":968},", bar);\n",[958,3755,3756],{"class":960,"line":1107},[958,3757,3647],{"class":968},[934,3759,3760],{},"As you can imagine, this pattern could quickly bloat your routers. When I first ran into this problem, I attempted to do some parsing of the actual function definitions with regular expressions to *magically” map the parameters, which would have worked — but only if I had followed specific constraints. So, I scrapped the idea (I might still throw this into a Backbone plugin sometime).",[934,3762,3763],{},"The code above now transforms into something much more maintainable:",[949,3765,3767],{"className":951,"code":3766,"language":953,"meta":954,"style":954},"routes: {\n    'base\u002F:foo': 'search',\n    'base\u002F:bar': 'search',\n    'base\u002F:foo\u002F:bar': 'search'\n},\n\nsearch: function() {\n    var foo, bar, i;\n\n    for(i = arguments.length - 1; i >= 0; i--) {\n\n        if(arguments[i] === 'something to determine foo') {\n            foo = arguments[i];\n            continue;\n        }\n        else if(arguments[i] === 'something to determine bar') {\n            bar = arguments[i];\n            continue;\n        }\n    }\n},\n",[944,3768,3769,3775,3787,3798,3807,3811,3815,3825,3832,3836,3877,3881,3901,3913,3920,3924,3945,3956,3962,3966,3970],{"__ignoreMap":954},[958,3770,3771,3773],{"class":960,"line":961},[958,3772,3606],{"class":978},[958,3774,1741],{"class":968},[958,3776,3777,3780,3782,3785],{"class":960,"line":985},[958,3778,3779],{"class":997},"    'base\u002F:foo'",[958,3781,1126],{"class":968},[958,3783,3784],{"class":997},"'search'",[958,3786,1026],{"class":968},[958,3788,3789,3792,3794,3796],{"class":960,"line":991},[958,3790,3791],{"class":997},"    'base\u002F:bar'",[958,3793,1126],{"class":968},[958,3795,3784],{"class":997},[958,3797,1026],{"class":968},[958,3799,3800,3803,3805],{"class":960,"line":1004},[958,3801,3802],{"class":997},"    'base\u002F:foo\u002F:bar'",[958,3804,1126],{"class":968},[958,3806,3642],{"class":997},[958,3808,3809],{"class":960,"line":1010},[958,3810,3647],{"class":968},[958,3812,3813],{"class":960,"line":1016},[958,3814,1117],{"emptyLinePlaceholder":1116},[958,3816,3817,3819,3821,3823],{"class":960,"line":1029},[958,3818,3656],{"class":978},[958,3820,1126],{"class":968},[958,3822,1129],{"class":964},[958,3824,2913],{"class":968},[958,3826,3827,3829],{"class":960,"line":1040},[958,3828,2644],{"class":964},[958,3830,3831],{"class":968}," foo, bar, i;\n",[958,3833,3834],{"class":960,"line":1046},[958,3835,1117],{"emptyLinePlaceholder":1116},[958,3837,3838,3841,3844,3846,3849,3851,3854,3857,3860,3863,3866,3869,3872,3875],{"class":960,"line":1052},[958,3839,3840],{"class":964},"    for",[958,3842,3843],{"class":968},"(i ",[958,3845,972],{"class":964},[958,3847,3848],{"class":1022}," arguments",[958,3850,1155],{"class":968},[958,3852,3853],{"class":1022},"length",[958,3855,3856],{"class":964}," -",[958,3858,3859],{"class":1022}," 1",[958,3861,3862],{"class":968},"; i ",[958,3864,3865],{"class":964},">=",[958,3867,3868],{"class":1022}," 0",[958,3870,3871],{"class":968},"; i",[958,3873,3874],{"class":964},"--",[958,3876,1196],{"class":968},[958,3878,3879],{"class":960,"line":1062},[958,3880,1117],{"emptyLinePlaceholder":1116},[958,3882,3883,3885,3887,3890,3893,3896,3899],{"class":960,"line":1072},[958,3884,1934],{"class":964},[958,3886,1143],{"class":968},[958,3888,3889],{"class":1022},"arguments",[958,3891,3892],{"class":968},"[i] ",[958,3894,3895],{"class":964},"===",[958,3897,3898],{"class":997}," 'something to determine foo'",[958,3900,1196],{"class":968},[958,3902,3903,3906,3908,3910],{"class":960,"line":1077},[958,3904,3905],{"class":968},"            foo ",[958,3907,972],{"class":964},[958,3909,3848],{"class":1022},[958,3911,3912],{"class":968},"[i];\n",[958,3914,3915,3918],{"class":960,"line":1083},[958,3916,3917],{"class":964},"            continue",[958,3919,1951],{"class":968},[958,3921,3922],{"class":960,"line":1093},[958,3923,1788],{"class":968},[958,3925,3926,3929,3932,3934,3936,3938,3940,3943],{"class":960,"line":1102},[958,3927,3928],{"class":964},"        else",[958,3930,3931],{"class":964}," if",[958,3933,1143],{"class":968},[958,3935,3889],{"class":1022},[958,3937,3892],{"class":968},[958,3939,3895],{"class":964},[958,3941,3942],{"class":997}," 'something to determine bar'",[958,3944,1196],{"class":968},[958,3946,3947,3950,3952,3954],{"class":960,"line":1107},[958,3948,3949],{"class":968},"            bar ",[958,3951,972],{"class":964},[958,3953,3848],{"class":1022},[958,3955,3912],{"class":968},[958,3957,3958,3960],{"class":960,"line":1113},[958,3959,3917],{"class":964},[958,3961,1951],{"class":968},[958,3963,3964],{"class":960,"line":1120},[958,3965,1788],{"class":968},[958,3967,3968],{"class":960,"line":1135},[958,3969,2023],{"class":968},[958,3971,3972],{"class":960,"line":1169},[958,3973,3647],{"class":968},[934,3975,3976,3977,3980],{},"This pattern can drastically reduce router bloat. However, be aware that it will not work for parameters that are not distinguishable. For example, if you had two parameters that were both IDs and followed the pattern ",[944,3978,3979],{},"XXXX-XXXX",", you would not be able to identify which ID corresponded to which parameter.",[929,3982,3984],{"id":3983},"modelfetch-wont-clear-your-model","model.fetch() Won’t Clear Your Model",[934,3986,3987,3988,3991,3992,1866,3995,3505,3998,4001,4002,4004,4005,4007,4008,4010,4011,3505,4013,4015],{},"This usually trips up those who are new to Backbone.js: ",[944,3989,3990],{},"model.fetch()"," will not clear out your model, but rather extends the attributes of your model. Therefore, if your model has attributes ",[944,3993,3994],{},"x",[944,3996,3997],{},"y",[944,3999,4000],{},"z"," and your fetch returns ",[944,4003,3997],{},"and ",[944,4006,4000],{},", then ",[944,4009,3994],{}," will still be in the model and only ",[944,4012,3997],{},[944,4014,4000],{}," will be updated. The following example visualizes this concept.",[949,4017,4019],{"className":951,"code":4018,"language":953,"meta":954,"style":954},"var Model = Backbone.Model.extend({\n  defaults: {\n    x: 1,\n    y: 1,\n    z: 1,\n  },\n});\nvar model = new Model();\n\u002F* model.attributes yields\n{\n    x: 1,\n    y: 1,\n    z: 1\n} *\u002F\nmodel.fetch();\n\u002F* let’s assume that the endpoint returns this\n{\n    y: 2,\n    z: 2,\n} *\u002F\n\u002F* model.attributes now yields\n{\n    x: 1,\n    y: 2,\n    z: 2\n} *\u002F\n",[944,4020,4021,4035,4039,4048,4057,4066,4070,4074,4090,4095,4099,4104,4109,4114,4119,4129,4134,4138,4143,4148,4152,4157,4161,4165,4169,4174],{"__ignoreMap":954},[958,4022,4023,4025,4027,4029,4031,4033],{"class":960,"line":961},[958,4024,965],{"class":964},[958,4026,2386],{"class":968},[958,4028,972],{"class":964},[958,4030,975],{"class":968},[958,4032,979],{"class":978},[958,4034,982],{"class":968},[958,4036,4037],{"class":960,"line":985},[958,4038,988],{"class":968},[958,4040,4041,4044,4046],{"class":960,"line":991},[958,4042,4043],{"class":968},"    x: ",[958,4045,2424],{"class":1022},[958,4047,1026],{"class":968},[958,4049,4050,4053,4055],{"class":960,"line":1004},[958,4051,4052],{"class":968},"    y: ",[958,4054,2424],{"class":1022},[958,4056,1026],{"class":968},[958,4058,4059,4062,4064],{"class":960,"line":1010},[958,4060,4061],{"class":968},"    z: ",[958,4063,2424],{"class":1022},[958,4065,1026],{"class":968},[958,4067,4068],{"class":960,"line":1016},[958,4069,1231],{"class":968},[958,4071,4072],{"class":960,"line":1029},[958,4073,1237],{"class":968},[958,4075,4076,4078,4081,4083,4085,4088],{"class":960,"line":1040},[958,4077,965],{"class":964},[958,4079,4080],{"class":968}," model ",[958,4082,972],{"class":964},[958,4084,1821],{"class":964},[958,4086,4087],{"class":978}," Model",[958,4089,3487],{"class":968},[958,4091,4092],{"class":960,"line":1046},[958,4093,4094],{"class":1448},"\u002F* model.attributes yields\n",[958,4096,4097],{"class":960,"line":1052},[958,4098,2120],{"class":1448},[958,4100,4101],{"class":960,"line":1062},[958,4102,4103],{"class":1448},"    x: 1,\n",[958,4105,4106],{"class":960,"line":1072},[958,4107,4108],{"class":1448},"    y: 1,\n",[958,4110,4111],{"class":960,"line":1077},[958,4112,4113],{"class":1448},"    z: 1\n",[958,4115,4116],{"class":960,"line":1083},[958,4117,4118],{"class":1448},"} *\u002F\n",[958,4120,4121,4124,4127],{"class":960,"line":1093},[958,4122,4123],{"class":968},"model.",[958,4125,4126],{"class":978},"fetch",[958,4128,3487],{"class":968},[958,4130,4131],{"class":960,"line":1102},[958,4132,4133],{"class":1448},"\u002F* let’s assume that the endpoint returns this\n",[958,4135,4136],{"class":960,"line":1107},[958,4137,2120],{"class":1448},[958,4139,4140],{"class":960,"line":1113},[958,4141,4142],{"class":1448},"    y: 2,\n",[958,4144,4145],{"class":960,"line":1120},[958,4146,4147],{"class":1448},"    z: 2,\n",[958,4149,4150],{"class":960,"line":1135},[958,4151,4118],{"class":1448},[958,4153,4154],{"class":960,"line":1169},[958,4155,4156],{"class":1448},"\u002F* model.attributes now yields\n",[958,4158,4159],{"class":960,"line":1174},[958,4160,2120],{"class":1448},[958,4162,4163],{"class":960,"line":1179},[958,4164,4103],{"class":1448},[958,4166,4167],{"class":960,"line":1199},[958,4168,4142],{"class":1448},[958,4170,4171],{"class":960,"line":1223},[958,4172,4173],{"class":1448},"    z: 2\n",[958,4175,4176],{"class":960,"line":1228},[958,4177,4118],{"class":1448},[929,4179,4181],{"id":4180},"puts-require-an-id-attribute","PUTs Require An ID Attribute",[934,4183,4184,4185,4190,4191,4194],{},"This one also usually trips up those who are new to Backbone.js. To have your models send a ",[2253,4186,4189],{"href":4187,"rel":4188},"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHypertext_Transfer_Protocol#Request_methods",[3503],"HTTP PUT"," request when you call ",[944,4192,4193],{},".save()",", your model is required to have an ID attribute set. Remember that the HTTP PUT verb is designed to be an update, so it makes sense that to send a PUT request, your model is required to have an ID. In an ideal world, all of your models would have a perfect ID attribute named ID, but the JSON data that you receive from your endpoints will likely not always have perfectly named IDs.",[934,4196,4197,4198,4201,4202,1155],{},"Therefore, if you need to update a model, be sure that an ID is on the model before saving it. Backbone.js versions 0.5 and greater allow you to change the name of the ID attribute of your models using ",[944,4199,4200],{},"idAttribute",", in case your endpoint doesn’t return IDs named ",[944,4203,4204],{},"id",[934,4206,4207,4208,4211,4212,1155],{},"If are stuck using a version of Backbone.js lower than 0.5, I suggest that you modify the ",[944,4209,4210],{},"parse"," function of your collection or model to map your expected ID attribute to the attribute ID. Here’s a quick example of how you can achieve this by modifying your parse function. Let’s imagine you have a collection of cars whose IDs are ",[944,4213,4214],{},"carID",[949,4216,4218],{"className":951,"code":4217,"language":953,"meta":954,"style":954},"parse: function(response) {\n\n    _.each(response.cars, function(car, i) {\n        \u002F\u002F map the returned ID of carID to the correct attribute ID\n        response.cars[i].id = response.cars[i].carID;\n    });\n\n    return response;\n},```\n\n### Model Data On Page Load\n\nSometimes you will find that your models or collections need to be initialized with data on page load. Many articles about Backbone.js patterns, such as Rico Sta Cruz’ *Backbone Patterns” and Katz’ *Avoiding Common Backbone.js Pitfalls,” discuss this pattern. This pattern is easily achieved by inlining a script on the page and rendering out the data in either single-model attributes or JSON, using the server-side language of your choice. For example, in Rails, I use one of the following:\n\n```js\n\u002F\u002F a single attribute\nvar model = new Model({\n    hello:\n});\n\u002F\u002F or to have JSON\nvar model = new Model();\n",[944,4219,4220,4235,4239,4263,4268,4278,4283,4287,4294,4302,4306,4311,4315,4320,4324,4332,4337,4351,4356,4360,4365],{"__ignoreMap":954},[958,4221,4222,4224,4226,4228,4230,4233],{"class":960,"line":961},[958,4223,4210],{"class":978},[958,4225,1126],{"class":968},[958,4227,1129],{"class":964},[958,4229,1143],{"class":968},[958,4231,4232],{"class":1192},"response",[958,4234,1196],{"class":968},[958,4236,4237],{"class":960,"line":985},[958,4238,1117],{"emptyLinePlaceholder":1116},[958,4240,4241,4244,4246,4249,4251,4253,4256,4258,4261],{"class":960,"line":991},[958,4242,4243],{"class":968},"    _.",[958,4245,1457],{"class":978},[958,4247,4248],{"class":968},"(response.cars, ",[958,4250,1129],{"class":964},[958,4252,1143],{"class":968},[958,4254,4255],{"class":1192},"car",[958,4257,1866],{"class":968},[958,4259,4260],{"class":1192},"i",[958,4262,1196],{"class":968},[958,4264,4265],{"class":960,"line":1004},[958,4266,4267],{"class":1448},"        \u002F\u002F map the returned ID of carID to the correct attribute ID\n",[958,4269,4270,4273,4275],{"class":960,"line":1010},[958,4271,4272],{"class":968},"        response.cars[i].id ",[958,4274,972],{"class":964},[958,4276,4277],{"class":968}," response.cars[i].carID;\n",[958,4279,4280],{"class":960,"line":1016},[958,4281,4282],{"class":968},"    });\n",[958,4284,4285],{"class":960,"line":1029},[958,4286,1117],{"emptyLinePlaceholder":1116},[958,4288,4289,4291],{"class":960,"line":1040},[958,4290,2700],{"class":964},[958,4292,4293],{"class":968}," response;\n",[958,4295,4296,4299],{"class":960,"line":1046},[958,4297,4298],{"class":968},"},",[958,4300,4301],{"class":997},"```\n",[958,4303,4304],{"class":960,"line":1052},[958,4305,1117],{"emptyLinePlaceholder":1116},[958,4307,4308],{"class":960,"line":1062},[958,4309,4310],{"class":997},"### Model Data On Page Load\n",[958,4312,4313],{"class":960,"line":1072},[958,4314,1117],{"emptyLinePlaceholder":1116},[958,4316,4317],{"class":960,"line":1077},[958,4318,4319],{"class":997},"Sometimes you will find that your models or collections need to be initialized with data on page load. Many articles about Backbone.js patterns, such as Rico Sta Cruz’ *Backbone Patterns” and Katz’ *Avoiding Common Backbone.js Pitfalls,” discuss this pattern. This pattern is easily achieved by inlining a script on the page and rendering out the data in either single-model attributes or JSON, using the server-side language of your choice. For example, in Rails, I use one of the following:\n",[958,4321,4322],{"class":960,"line":1083},[958,4323,1117],{"emptyLinePlaceholder":1116},[958,4325,4326,4329],{"class":960,"line":1093},[958,4327,4328],{"class":997},"```",[958,4330,4331],{"class":968},"js\n",[958,4333,4334],{"class":960,"line":1102},[958,4335,4336],{"class":1448},"\u002F\u002F a single attribute\n",[958,4338,4339,4341,4343,4345,4347,4349],{"class":960,"line":1107},[958,4340,965],{"class":964},[958,4342,4080],{"class":968},[958,4344,972],{"class":964},[958,4346,1821],{"class":964},[958,4348,4087],{"class":978},[958,4350,982],{"class":968},[958,4352,4353],{"class":960,"line":1113},[958,4354,4355],{"class":968},"    hello:\n",[958,4357,4358],{"class":960,"line":1120},[958,4359,1237],{"class":968},[958,4361,4362],{"class":960,"line":1135},[958,4363,4364],{"class":1448},"\u002F\u002F or to have JSON\n",[958,4366,4367,4369,4371,4373,4375,4377],{"class":960,"line":1169},[958,4368,965],{"class":964},[958,4370,4080],{"class":968},[958,4372,972],{"class":964},[958,4374,1821],{"class":964},[958,4376,4087],{"class":978},[958,4378,3487],{"class":968},[934,4380,4381],{},"Using this pattern could improve your search engine rankings by *instantly” rendering out your page, and it could drastically shorten the time it takes for your application to be up and running by limiting the application’s initial HTTP requests.",[924,4383,4385],{"id":4384},"handling-failed-model-attribute-validation","Handling Failed Model Attribute Validation",[934,4387,4388],{},"Very often, you will want to know what model attributes have failed validation. For example, if you have an extremely complex form field, you might want to know which model attribute has failed validation so that you can highlight the input field corresponding to the attribute. Unfortunately, alerting your views as to which model attributes have failed validation is not directly baked into Backbone.js, but you can use a few different pattern to handle this.",[924,4390,4392],{"id":4391},"return-an-error-object","RETURN AN ERROR OBJECT",[934,4394,4395],{},"One pattern to notify your views of which model attributes have failed validation is to pass back an object with some sort of flag detailing which attribute has failed validation, such as the following:",[949,4397,4399],{"className":951,"code":4398,"language":953,"meta":954,"style":954},"\u002F\u002F Inside your model\nvalidate: function(attrs) {\n    var errors = [];\n\n    if(attrs.a \u003C 0) {\n        errors.push({\n            'message': 'Form field a is messed up!',\n            'class': 'a'\n        });\n    }\n    if(attrs.b \u003C 0) {\n        errors.push({\n            'message': 'Form field b is messed up!',\n            'class': 'b'\n        });\n    }\n\n    if(errors.length) {\n        return errors;\n    }\n}\n\n\u002F\u002F Inside your view\nthis.model.on('invalid’, function(model, errors) {\n    _.each(errors, function(error, i) {\n        $(‘.’ + error.class).addClass('error');\n        alert(error.message);\n    });\n});\n",[944,4400,4401,4406,4422,4434,4438,4452,4462,4474,4484,4489,4493,4506,4514,4525,4534,4538,4542,4546,4557,4564,4568,4572,4576,4581,4597,4619,4641,4649,4653],{"__ignoreMap":954},[958,4402,4403],{"class":960,"line":961},[958,4404,4405],{"class":1448},"\u002F\u002F Inside your model\n",[958,4407,4408,4411,4413,4415,4417,4420],{"class":960,"line":985},[958,4409,4410],{"class":978},"validate",[958,4412,1126],{"class":968},[958,4414,1129],{"class":964},[958,4416,1143],{"class":968},[958,4418,4419],{"class":1192},"attrs",[958,4421,1196],{"class":968},[958,4423,4424,4426,4429,4431],{"class":960,"line":991},[958,4425,2644],{"class":964},[958,4427,4428],{"class":968}," errors ",[958,4430,972],{"class":964},[958,4432,4433],{"class":968}," [];\n",[958,4435,4436],{"class":960,"line":1004},[958,4437,1117],{"emptyLinePlaceholder":1116},[958,4439,4440,4443,4446,4448,4450],{"class":960,"line":1010},[958,4441,4442],{"class":964},"    if",[958,4444,4445],{"class":968},"(attrs.a ",[958,4447,2233],{"class":964},[958,4449,3868],{"class":1022},[958,4451,1196],{"class":968},[958,4453,4454,4457,4460],{"class":960,"line":1016},[958,4455,4456],{"class":968},"        errors.",[958,4458,4459],{"class":978},"push",[958,4461,982],{"class":968},[958,4463,4464,4467,4469,4472],{"class":960,"line":1029},[958,4465,4466],{"class":997},"            'message'",[958,4468,1126],{"class":968},[958,4470,4471],{"class":997},"'Form field a is messed up!'",[958,4473,1026],{"class":968},[958,4475,4476,4479,4481],{"class":960,"line":1040},[958,4477,4478],{"class":997},"            'class'",[958,4480,1126],{"class":968},[958,4482,4483],{"class":997},"'a'\n",[958,4485,4486],{"class":960,"line":1046},[958,4487,4488],{"class":968},"        });\n",[958,4490,4491],{"class":960,"line":1052},[958,4492,2023],{"class":968},[958,4494,4495,4497,4500,4502,4504],{"class":960,"line":1062},[958,4496,4442],{"class":964},[958,4498,4499],{"class":968},"(attrs.b ",[958,4501,2233],{"class":964},[958,4503,3868],{"class":1022},[958,4505,1196],{"class":968},[958,4507,4508,4510,4512],{"class":960,"line":1072},[958,4509,4456],{"class":968},[958,4511,4459],{"class":978},[958,4513,982],{"class":968},[958,4515,4516,4518,4520,4523],{"class":960,"line":1077},[958,4517,4466],{"class":997},[958,4519,1126],{"class":968},[958,4521,4522],{"class":997},"'Form field b is messed up!'",[958,4524,1026],{"class":968},[958,4526,4527,4529,4531],{"class":960,"line":1083},[958,4528,4478],{"class":997},[958,4530,1126],{"class":968},[958,4532,4533],{"class":997},"'b'\n",[958,4535,4536],{"class":960,"line":1093},[958,4537,4488],{"class":968},[958,4539,4540],{"class":960,"line":1102},[958,4541,2023],{"class":968},[958,4543,4544],{"class":960,"line":1107},[958,4545,1117],{"emptyLinePlaceholder":1116},[958,4547,4548,4550,4553,4555],{"class":960,"line":1113},[958,4549,4442],{"class":964},[958,4551,4552],{"class":968},"(errors.",[958,4554,3853],{"class":1022},[958,4556,1196],{"class":968},[958,4558,4559,4561],{"class":960,"line":1120},[958,4560,3048],{"class":964},[958,4562,4563],{"class":968}," errors;\n",[958,4565,4566],{"class":960,"line":1135},[958,4567,2023],{"class":968},[958,4569,4570],{"class":960,"line":1169},[958,4571,1658],{"class":968},[958,4573,4574],{"class":960,"line":1174},[958,4575,1117],{"emptyLinePlaceholder":1116},[958,4577,4578],{"class":960,"line":1179},[958,4579,4580],{"class":1448},"\u002F\u002F Inside your view\n",[958,4582,4583,4585,4587,4589,4591,4594],{"class":960,"line":1199},[958,4584,1152],{"class":1022},[958,4586,2609],{"class":968},[958,4588,2829],{"class":978},[958,4590,1143],{"class":968},[958,4592,4593],{"class":997},"'invalid’, function(model, errors) ",[958,4595,2120],{"class":4596},"s7hpK",[958,4598,4599,4601,4603,4606,4608,4610,4613,4615,4617],{"class":960,"line":1223},[958,4600,4243],{"class":968},[958,4602,1457],{"class":978},[958,4604,4605],{"class":968},"(errors, ",[958,4607,1129],{"class":964},[958,4609,1143],{"class":968},[958,4611,4612],{"class":1192},"error",[958,4614,1866],{"class":968},[958,4616,4260],{"class":1192},[958,4618,1196],{"class":968},[958,4620,4621,4623,4626,4629,4632,4634,4636,4639],{"class":960,"line":1228},[958,4622,2918],{"class":978},[958,4624,4625],{"class":968},"(‘.’ ",[958,4627,4628],{"class":964},"+",[958,4630,4631],{"class":968}," error.class).",[958,4633,2689],{"class":978},[958,4635,1143],{"class":968},[958,4637,4638],{"class":997},"'error'",[958,4640,2057],{"class":968},[958,4642,4643,4646],{"class":960,"line":1234},[958,4644,4645],{"class":978},"        alert",[958,4647,4648],{"class":968},"(error.message);\n",[958,4650,4651],{"class":960,"line":1472},[958,4652,4282],{"class":968},[958,4654,4655],{"class":960,"line":1483},[958,4656,1237],{"class":968},[934,4658,4659,4660,4663,4664,4667],{},"The advantage of this pattern is that you are handling all invalid messages in one location. The disadvantage is that your invalid method could become a large",[944,4661,4662],{},"switch"," or ",[944,4665,4666],{},"if"," statement if you deal with invalid attributes differently.",[924,4669,4671],{"id":4670},"broadcast-custom-error-event","BROADCAST CUSTOM ERROR EVENT",[934,4673,4674],{},"An alternative pattern, suggested by a friend of mine, Derick Bailey, is to trigger custom errors events for each model attribute. This allows your views to bind to specific error events for individual attributes:",[949,4676,4678],{"className":951,"code":4677,"language":953,"meta":954,"style":954},"\u002F\u002F Inside your model\nvalidate: function(attrs) {\n\n    if(attrs.a \u003C 0) {\n            this.trigger(‘invalid:a’, 'Form field a is messed up!', this);\n    }\n    if(attrs.b \u003C 0) {\n            this.trigger(‘invalid:b’, 'Form field b is messed up!', this);\n    }\n}\n\n\u002F\u002F Inside your view\nthis.model.on('invalid:a’, function(error) {\n        $(‘a’).addClass('error');\n        alert(error);\n});\n\nthis.model.on('invalid:b’, function(error) {\n        $(‘b’).addClass('error');\n        alert(error);\n});\n",[944,4679,4680,4684,4698,4702,4714,4735,4739,4751,4770,4774,4778,4782,4786,4801,4816,4823,4827,4831,4846,4861,4867],{"__ignoreMap":954},[958,4681,4682],{"class":960,"line":961},[958,4683,4405],{"class":1448},[958,4685,4686,4688,4690,4692,4694,4696],{"class":960,"line":985},[958,4687,4410],{"class":978},[958,4689,1126],{"class":968},[958,4691,1129],{"class":964},[958,4693,1143],{"class":968},[958,4695,4419],{"class":1192},[958,4697,1196],{"class":968},[958,4699,4700],{"class":960,"line":991},[958,4701,1117],{"emptyLinePlaceholder":1116},[958,4703,4704,4706,4708,4710,4712],{"class":960,"line":1004},[958,4705,4442],{"class":964},[958,4707,4445],{"class":968},[958,4709,2233],{"class":964},[958,4711,3868],{"class":1022},[958,4713,1196],{"class":968},[958,4715,4716,4719,4721,4724,4727,4729,4731,4733],{"class":960,"line":1010},[958,4717,4718],{"class":1022},"            this",[958,4720,1155],{"class":968},[958,4722,4723],{"class":978},"trigger",[958,4725,4726],{"class":968},"(‘invalid:a’, ",[958,4728,4471],{"class":997},[958,4730,1866],{"class":968},[958,4732,1152],{"class":1022},[958,4734,2057],{"class":968},[958,4736,4737],{"class":960,"line":1016},[958,4738,2023],{"class":968},[958,4740,4741,4743,4745,4747,4749],{"class":960,"line":1029},[958,4742,4442],{"class":964},[958,4744,4499],{"class":968},[958,4746,2233],{"class":964},[958,4748,3868],{"class":1022},[958,4750,1196],{"class":968},[958,4752,4753,4755,4757,4759,4762,4764,4766,4768],{"class":960,"line":1040},[958,4754,4718],{"class":1022},[958,4756,1155],{"class":968},[958,4758,4723],{"class":978},[958,4760,4761],{"class":968},"(‘invalid:b’, ",[958,4763,4522],{"class":997},[958,4765,1866],{"class":968},[958,4767,1152],{"class":1022},[958,4769,2057],{"class":968},[958,4771,4772],{"class":960,"line":1046},[958,4773,2023],{"class":968},[958,4775,4776],{"class":960,"line":1052},[958,4777,1658],{"class":968},[958,4779,4780],{"class":960,"line":1062},[958,4781,1117],{"emptyLinePlaceholder":1116},[958,4783,4784],{"class":960,"line":1072},[958,4785,4580],{"class":1448},[958,4787,4788,4790,4792,4794,4796,4799],{"class":960,"line":1077},[958,4789,1152],{"class":1022},[958,4791,2609],{"class":968},[958,4793,2829],{"class":978},[958,4795,1143],{"class":968},[958,4797,4798],{"class":997},"'invalid:a’, function(error) ",[958,4800,2120],{"class":4596},[958,4802,4803,4805,4808,4810,4812,4814],{"class":960,"line":1083},[958,4804,2918],{"class":978},[958,4806,4807],{"class":968},"(‘a’).",[958,4809,2689],{"class":978},[958,4811,1143],{"class":968},[958,4813,4638],{"class":997},[958,4815,2057],{"class":968},[958,4817,4818,4820],{"class":960,"line":1093},[958,4819,4645],{"class":978},[958,4821,4822],{"class":968},"(error);\n",[958,4824,4825],{"class":960,"line":1102},[958,4826,1237],{"class":968},[958,4828,4829],{"class":960,"line":1107},[958,4830,1117],{"emptyLinePlaceholder":1116},[958,4832,4833,4835,4837,4839,4841,4844],{"class":960,"line":1113},[958,4834,1152],{"class":1022},[958,4836,2609],{"class":968},[958,4838,2829],{"class":978},[958,4840,1143],{"class":968},[958,4842,4843],{"class":997},"'invalid:b’, function(error) ",[958,4845,2120],{"class":4596},[958,4847,4848,4850,4853,4855,4857,4859],{"class":960,"line":1120},[958,4849,2918],{"class":978},[958,4851,4852],{"class":968},"(‘b’).",[958,4854,2689],{"class":978},[958,4856,1143],{"class":968},[958,4858,4638],{"class":997},[958,4860,2057],{"class":968},[958,4862,4863,4865],{"class":960,"line":1135},[958,4864,4645],{"class":978},[958,4866,4822],{"class":968},[958,4868,4869],{"class":960,"line":1169},[958,4870,1237],{"class":968},[934,4872,4873],{},"The advantage of this pattern is that your view bindings are explicit in the type of error they are bound to, and if you have specific instructions for each type of attribute error, it can clean up your view code and make it more maintainable. The one downside of this pattern is that your views could become rather bloated if there aren’t many differences in how you handle different attribute errors.",[934,4875,4876],{},"Both patterns have their pros and cons, and you should think about which pattern is best for your use case. If you treat all failed validation errors the same way, then the first approach would probably be best; if you have specific UI changes per model attribute, then the latter approach would be better.",[929,4878,4880],{"id":4879},"http-status-code-200-trigger-error","HTTP Status Code 200 Trigger Error",[934,4882,4883,4884,4888],{},"If the endpoint that your model or collection is hitting returns invalid JSON, then your model or collection will trigger an *error” event, even if the endpoint returns a 200 HTTP status code. This issue mostly comes up when developing locally against mock JSON data. So, a good rule of thumb is to throw any mock JSON files you’re developing through a ",[2253,4885,4887],{"href":4886},"http:\u002F\u002Fjsonformatter.curiousconcept.com\u002F","JSON validator",". Or get a plugin for your IDE that will catch any ill-formatted JSON.",[929,4890,4892],{"id":4891},"create-a-generic-error-display","Create A Generic Error Display",[934,4894,4895],{},"This one could save you time and create a uniform pattern for handling and visualizing error messages, which will improve your user’s overall experience. In any Backbone.js app that I develop, I create a generic view that handles alerts:",[949,4897,4899],{"className":951,"code":4898,"language":953,"meta":954,"style":954},"var AlertView = Backbone.View.extend({\n    set: function(typeOfError, message) {\n        var alert = $(‘.in-page-alert’).length ? $(‘.in-page-alert’): $(‘.body-alert’);\n        alert\n            .removeClass(‘error success warning’)\n            .addClass(typeOfError)\n            .html(message)\n            .fadeIn()\n            .delay(5000)\n            .fadeOut();\n    }\n});\n",[944,4900,4901,4916,4937,4993,4998,5007,5016,5025,5034,5049,5058,5062],{"__ignoreMap":954},[958,4902,4903,4905,4908,4910,4912,4914],{"class":960,"line":961},[958,4904,965],{"class":964},[958,4906,4907],{"class":968}," AlertView ",[958,4909,972],{"class":964},[958,4911,2510],{"class":968},[958,4913,979],{"class":978},[958,4915,982],{"class":968},[958,4917,4918,4921,4923,4925,4927,4930,4932,4935],{"class":960,"line":985},[958,4919,4920],{"class":978},"    set",[958,4922,1126],{"class":968},[958,4924,1129],{"class":964},[958,4926,1143],{"class":968},[958,4928,4929],{"class":1192},"typeOfError",[958,4931,1866],{"class":968},[958,4933,4934],{"class":1192},"message",[958,4936,1196],{"class":968},[958,4938,4939,4941,4944,4946,4948,4951,4954,4957,4959,4962,4964,4967,4969,4971,4973,4975,4977,4980,4983,4985,4988,4990],{"class":960,"line":991},[958,4940,2972],{"class":964},[958,4942,4943],{"class":968}," alert ",[958,4945,972],{"class":964},[958,4947,2652],{"class":978},[958,4949,4950],{"class":968},"(‘.in",[958,4952,4953],{"class":964},"-",[958,4955,4956],{"class":968},"page",[958,4958,4953],{"class":964},[958,4960,4961],{"class":968},"alert’).",[958,4963,3853],{"class":1022},[958,4965,4966],{"class":964}," ?",[958,4968,2652],{"class":978},[958,4970,4950],{"class":968},[958,4972,4953],{"class":964},[958,4974,4956],{"class":968},[958,4976,4953],{"class":964},[958,4978,4979],{"class":968},"alert’)",[958,4981,4982],{"class":964},":",[958,4984,2652],{"class":978},[958,4986,4987],{"class":968},"(‘.body",[958,4989,4953],{"class":964},[958,4991,4992],{"class":968},"alert’);\n",[958,4994,4995],{"class":960,"line":1004},[958,4996,4997],{"class":968},"        alert\n",[958,4999,5000,5002,5004],{"class":960,"line":1010},[958,5001,3471],{"class":968},[958,5003,2674],{"class":978},[958,5005,5006],{"class":968},"(‘error success warning’)\n",[958,5008,5009,5011,5013],{"class":960,"line":1016},[958,5010,3471],{"class":968},[958,5012,2689],{"class":978},[958,5014,5015],{"class":968},"(typeOfError)\n",[958,5017,5018,5020,5022],{"class":960,"line":1029},[958,5019,3471],{"class":968},[958,5021,383],{"class":978},[958,5023,5024],{"class":968},"(message)\n",[958,5026,5027,5029,5032],{"class":960,"line":1040},[958,5028,3471],{"class":968},[958,5030,5031],{"class":978},"fadeIn",[958,5033,3477],{"class":968},[958,5035,5036,5038,5041,5043,5046],{"class":960,"line":1046},[958,5037,3471],{"class":968},[958,5039,5040],{"class":978},"delay",[958,5042,1143],{"class":968},[958,5044,5045],{"class":1022},"5000",[958,5047,5048],{"class":968},")\n",[958,5050,5051,5053,5056],{"class":960,"line":1052},[958,5052,3471],{"class":968},[958,5054,5055],{"class":978},"fadeOut",[958,5057,3487],{"class":968},[958,5059,5060],{"class":960,"line":1062},[958,5061,2023],{"class":968},[958,5063,5064],{"class":960,"line":1072},[958,5065,1237],{"class":968},[934,5067,5068,5069,5072,5073,5076,5077,5079],{},"The view above first looks to see whether there is a view-specific ",[944,5070,5071],{},"in-page-alert","div, which you would declare inside of your view’s markup. If there is no view-specific div, then it falls back to a generic ",[944,5074,5075],{},"body-alert"," div, which you would declare somewhere in the layout. This enables you to deliver a consistent error message to your users and provides a useful fallback in case you forget to specify a view-specific ",[944,5078,5071],{}," div. The pattern above streamlines how you handle error messages in your views, as follows:",[949,5081,5083],{"className":951,"code":5082,"language":953,"meta":954,"style":954},"var alert = new AlertView();\n\nthis.model.on('error', function (model, error) {\n  alert.set('TYPE-OF-ERROR', error);\n});\n",[944,5084,5085,5100,5104,5131,5146],{"__ignoreMap":954},[958,5086,5087,5089,5091,5093,5095,5098],{"class":960,"line":961},[958,5088,965],{"class":964},[958,5090,4943],{"class":968},[958,5092,972],{"class":964},[958,5094,1821],{"class":964},[958,5096,5097],{"class":978}," AlertView",[958,5099,3487],{"class":968},[958,5101,5102],{"class":960,"line":985},[958,5103,1117],{"emptyLinePlaceholder":1116},[958,5105,5106,5108,5110,5112,5114,5116,5118,5120,5122,5125,5127,5129],{"class":960,"line":991},[958,5107,1152],{"class":1022},[958,5109,2609],{"class":968},[958,5111,2829],{"class":978},[958,5113,1143],{"class":968},[958,5115,4638],{"class":997},[958,5117,1866],{"class":968},[958,5119,1129],{"class":964},[958,5121,1189],{"class":968},[958,5123,5124],{"class":1192},"model",[958,5126,1866],{"class":968},[958,5128,4612],{"class":1192},[958,5130,1196],{"class":968},[958,5132,5133,5136,5138,5140,5143],{"class":960,"line":1004},[958,5134,5135],{"class":968},"  alert.",[958,5137,1858],{"class":978},[958,5139,1143],{"class":968},[958,5141,5142],{"class":997},"'TYPE-OF-ERROR'",[958,5144,5145],{"class":968},", error);\n",[958,5147,5148],{"class":960,"line":1010},[958,5149,1237],{"class":968},[929,5151,5153],{"id":5152},"update-single-page-app-document-titles","Update Single-Page App Document Titles",[934,5155,5156,5157,5161],{},"This is more of a usability concern than anything. If you’re developing a single-page application, remember to update the document title of each page! I’ve written a simple Backbone.js plugin, ",[2253,5158,5160],{"href":5159},"https:\u002F\u002Fgithub.com\u002Fpwhisenhunt\u002FBackbonejs-Router-Title-Helper","Backbone.js Router Title Helper",", that does this in a simple and elegant format by extending the Backbone.js router. It allows you to specify a title’s object literal, whose keys map to route function names and whose values are page titles.",[949,5163,5165],{"className":951,"code":5164,"language":953,"meta":954,"style":954},"Backbone.Router = Backbone.Router.extend({\n  initialize: function (options) {\n    var that = this;\n\n    this.on('route', function (router, route, params) {\n      if (that.titles) {\n        if (that.titles[router]) document.title = that.titles[router];\n        else if (that.titles.default) document.title = that.titles.default;\n        else\n          throw (\n            'Backbone.js Router Title Helper: No title found for route:' +\n            router +\n            ' and no default route specified.'\n          );\n      }\n    });\n  },\n});\n",[944,5166,5167,5181,5196,5209,5213,5247,5255,5267,5281,5286,5294,5302,5310,5315,5320,5325,5329,5333],{"__ignoreMap":954},[958,5168,5169,5172,5174,5177,5179],{"class":960,"line":961},[958,5170,5171],{"class":968},"Backbone.Router ",[958,5173,972],{"class":964},[958,5175,5176],{"class":968}," Backbone.Router.",[958,5178,979],{"class":978},[958,5180,982],{"class":968},[958,5182,5183,5186,5188,5190,5192,5194],{"class":960,"line":985},[958,5184,5185],{"class":978},"  initialize",[958,5187,1126],{"class":968},[958,5189,1129],{"class":964},[958,5191,1189],{"class":968},[958,5193,2812],{"class":1192},[958,5195,1196],{"class":968},[958,5197,5198,5200,5203,5205,5207],{"class":960,"line":991},[958,5199,2644],{"class":964},[958,5201,5202],{"class":968}," that ",[958,5204,972],{"class":964},[958,5206,3392],{"class":1022},[958,5208,1951],{"class":968},[958,5210,5211],{"class":960,"line":1004},[958,5212,1117],{"emptyLinePlaceholder":1116},[958,5214,5215,5217,5219,5221,5223,5226,5228,5230,5232,5235,5237,5240,5242,5245],{"class":960,"line":1010},[958,5216,3703],{"class":1022},[958,5218,1155],{"class":968},[958,5220,2829],{"class":978},[958,5222,1143],{"class":968},[958,5224,5225],{"class":997},"'route'",[958,5227,1866],{"class":968},[958,5229,1129],{"class":964},[958,5231,1189],{"class":968},[958,5233,5234],{"class":1192},"router",[958,5236,1866],{"class":968},[958,5238,5239],{"class":1192},"route",[958,5241,1866],{"class":968},[958,5243,5244],{"class":1192},"params",[958,5246,1196],{"class":968},[958,5248,5249,5252],{"class":960,"line":1016},[958,5250,5251],{"class":964},"      if",[958,5253,5254],{"class":968}," (that.titles) {\n",[958,5256,5257,5259,5262,5264],{"class":960,"line":1029},[958,5258,1934],{"class":964},[958,5260,5261],{"class":968}," (that.titles[router]) document.title ",[958,5263,972],{"class":964},[958,5265,5266],{"class":968}," that.titles[router];\n",[958,5268,5269,5271,5273,5276,5278],{"class":960,"line":1040},[958,5270,3928],{"class":964},[958,5272,3931],{"class":964},[958,5274,5275],{"class":968}," (that.titles.default) document.title ",[958,5277,972],{"class":964},[958,5279,5280],{"class":968}," that.titles.default;\n",[958,5282,5283],{"class":960,"line":1046},[958,5284,5285],{"class":964},"        else\n",[958,5287,5288,5291],{"class":960,"line":1052},[958,5289,5290],{"class":964},"          throw",[958,5292,5293],{"class":968}," (\n",[958,5295,5296,5299],{"class":960,"line":1062},[958,5297,5298],{"class":997},"            'Backbone.js Router Title Helper: No title found for route:'",[958,5300,5301],{"class":964}," +\n",[958,5303,5304,5307],{"class":960,"line":1072},[958,5305,5306],{"class":968},"            router ",[958,5308,5309],{"class":964},"+\n",[958,5311,5312],{"class":960,"line":1077},[958,5313,5314],{"class":997},"            ' and no default route specified.'\n",[958,5316,5317],{"class":960,"line":1083},[958,5318,5319],{"class":968},"          );\n",[958,5321,5322],{"class":960,"line":1093},[958,5323,5324],{"class":968},"      }\n",[958,5326,5327],{"class":960,"line":1102},[958,5328,4282],{"class":968},[958,5330,5331],{"class":960,"line":1107},[958,5332,1231],{"class":968},[958,5334,5335],{"class":960,"line":1113},[958,5336,1237],{"class":968},[929,5338,5340],{"id":5339},"cache-objects-in-single-page-applications","CACHE OBJECTS IN SINGLE-PAGE applications",[934,5342,5343],{},"While we are on the topic of single-page applications, another pattern you could follow is to cache objects that will be reused! This case is fairly straightforward and simple:",[949,5345,5347],{"className":951,"code":5346,"language":953,"meta":954,"style":954},"\u002F\u002F Inside a router\ninitialize: function() {\n\n    this.cached = {\n        view: undefined,\n        model: undefined\n    }\n},\n\nindex: function(parameter) {\n    this.cached.model = this.cached.model || new Model({\n        parameter: parameter\n    });\n    this.cached.view = this.cached.view || new View({\n        model: this.cached.model\n    });\n}\n",[944,5348,5349,5354,5365,5369,5380,5389,5397,5401,5405,5409,5425,5447,5452,5456,5478,5487,5491],{"__ignoreMap":954},[958,5350,5351],{"class":960,"line":961},[958,5352,5353],{"class":1448},"\u002F\u002F Inside a router\n",[958,5355,5356,5359,5361,5363],{"class":960,"line":985},[958,5357,5358],{"class":978},"initialize",[958,5360,1126],{"class":968},[958,5362,1129],{"class":964},[958,5364,2913],{"class":968},[958,5366,5367],{"class":960,"line":991},[958,5368,1117],{"emptyLinePlaceholder":1116},[958,5370,5371,5373,5376,5378],{"class":960,"line":1004},[958,5372,3703],{"class":1022},[958,5374,5375],{"class":968},".cached ",[958,5377,972],{"class":964},[958,5379,1480],{"class":968},[958,5381,5382,5385,5387],{"class":960,"line":1010},[958,5383,5384],{"class":968},"        view: ",[958,5386,3713],{"class":1022},[958,5388,1026],{"class":968},[958,5390,5391,5394],{"class":960,"line":1016},[958,5392,5393],{"class":968},"        model: ",[958,5395,5396],{"class":1022},"undefined\n",[958,5398,5399],{"class":960,"line":1029},[958,5400,2023],{"class":968},[958,5402,5403],{"class":960,"line":1040},[958,5404,3647],{"class":968},[958,5406,5407],{"class":960,"line":1046},[958,5408,1117],{"emptyLinePlaceholder":1116},[958,5410,5411,5414,5416,5418,5420,5423],{"class":960,"line":1052},[958,5412,5413],{"class":978},"index",[958,5415,1126],{"class":968},[958,5417,1129],{"class":964},[958,5419,1143],{"class":968},[958,5421,5422],{"class":1192},"parameter",[958,5424,1196],{"class":968},[958,5426,5427,5429,5432,5434,5436,5438,5441,5443,5445],{"class":960,"line":1062},[958,5428,3703],{"class":1022},[958,5430,5431],{"class":968},".cached.model ",[958,5433,972],{"class":964},[958,5435,3392],{"class":1022},[958,5437,5431],{"class":968},[958,5439,5440],{"class":964},"||",[958,5442,1821],{"class":964},[958,5444,4087],{"class":978},[958,5446,982],{"class":968},[958,5448,5449],{"class":960,"line":1072},[958,5450,5451],{"class":968},"        parameter: parameter\n",[958,5453,5454],{"class":960,"line":1077},[958,5455,4282],{"class":968},[958,5457,5458,5460,5463,5465,5467,5469,5471,5473,5476],{"class":960,"line":1083},[958,5459,3703],{"class":1022},[958,5461,5462],{"class":968},".cached.view ",[958,5464,972],{"class":964},[958,5466,3392],{"class":1022},[958,5468,5462],{"class":968},[958,5470,5440],{"class":964},[958,5472,1821],{"class":964},[958,5474,5475],{"class":978}," View",[958,5477,982],{"class":968},[958,5479,5480,5482,5484],{"class":960,"line":1093},[958,5481,5393],{"class":968},[958,5483,1152],{"class":1022},[958,5485,5486],{"class":968},".cached.model\n",[958,5488,5489],{"class":960,"line":1102},[958,5490,4282],{"class":968},[958,5492,5493],{"class":960,"line":1107},[958,5494,1658],{"class":968},[934,5496,5497],{},"This pattern will give your application a small bump in speed because you won’t have to reinitialize your Backbone.js objects. However, it could cause your application’s memory footprint to grow rather large; so, I’ll typically only cache objects that are commonly used throughout an application. If you’ve developed Backbone.js apps in the past, then you’re likely asking yourself, *What if I want to fetch data?” You can fetch data each time the route is triggered:",[949,5499,5501],{"className":951,"code":5500,"language":953,"meta":954,"style":954},"\u002F\u002F Inside a router\ninitialize: function() {\n\n    this.cached = {\n        view: undefined,\n        model: undefined\n    }\n},\n\nindex: function(parameter) {\n    this.cached.model = this.cached.model || new Model({\n        parameter: parameter\n    });\n    this.cached.view = this.cached.view || new View({\n        model: this.cached.model\n    });\n    this.cached.model.fetch();\n}\n",[944,5502,5503,5507,5517,5521,5531,5539,5545,5549,5553,5557,5571,5591,5595,5599,5619,5627,5631,5642],{"__ignoreMap":954},[958,5504,5505],{"class":960,"line":961},[958,5506,5353],{"class":1448},[958,5508,5509,5511,5513,5515],{"class":960,"line":985},[958,5510,5358],{"class":978},[958,5512,1126],{"class":968},[958,5514,1129],{"class":964},[958,5516,2913],{"class":968},[958,5518,5519],{"class":960,"line":991},[958,5520,1117],{"emptyLinePlaceholder":1116},[958,5522,5523,5525,5527,5529],{"class":960,"line":1004},[958,5524,3703],{"class":1022},[958,5526,5375],{"class":968},[958,5528,972],{"class":964},[958,5530,1480],{"class":968},[958,5532,5533,5535,5537],{"class":960,"line":1010},[958,5534,5384],{"class":968},[958,5536,3713],{"class":1022},[958,5538,1026],{"class":968},[958,5540,5541,5543],{"class":960,"line":1016},[958,5542,5393],{"class":968},[958,5544,5396],{"class":1022},[958,5546,5547],{"class":960,"line":1029},[958,5548,2023],{"class":968},[958,5550,5551],{"class":960,"line":1040},[958,5552,3647],{"class":968},[958,5554,5555],{"class":960,"line":1046},[958,5556,1117],{"emptyLinePlaceholder":1116},[958,5558,5559,5561,5563,5565,5567,5569],{"class":960,"line":1052},[958,5560,5413],{"class":978},[958,5562,1126],{"class":968},[958,5564,1129],{"class":964},[958,5566,1143],{"class":968},[958,5568,5422],{"class":1192},[958,5570,1196],{"class":968},[958,5572,5573,5575,5577,5579,5581,5583,5585,5587,5589],{"class":960,"line":1062},[958,5574,3703],{"class":1022},[958,5576,5431],{"class":968},[958,5578,972],{"class":964},[958,5580,3392],{"class":1022},[958,5582,5431],{"class":968},[958,5584,5440],{"class":964},[958,5586,1821],{"class":964},[958,5588,4087],{"class":978},[958,5590,982],{"class":968},[958,5592,5593],{"class":960,"line":1072},[958,5594,5451],{"class":968},[958,5596,5597],{"class":960,"line":1077},[958,5598,4282],{"class":968},[958,5600,5601,5603,5605,5607,5609,5611,5613,5615,5617],{"class":960,"line":1083},[958,5602,3703],{"class":1022},[958,5604,5462],{"class":968},[958,5606,972],{"class":964},[958,5608,3392],{"class":1022},[958,5610,5462],{"class":968},[958,5612,5440],{"class":964},[958,5614,1821],{"class":964},[958,5616,5475],{"class":978},[958,5618,982],{"class":968},[958,5620,5621,5623,5625],{"class":960,"line":1093},[958,5622,5393],{"class":968},[958,5624,1152],{"class":1022},[958,5626,5486],{"class":968},[958,5628,5629],{"class":960,"line":1102},[958,5630,4282],{"class":968},[958,5632,5633,5635,5638,5640],{"class":960,"line":1107},[958,5634,3703],{"class":1022},[958,5636,5637],{"class":968},".cached.model.",[958,5639,4126],{"class":978},[958,5641,3487],{"class":968},[958,5643,5644],{"class":960,"line":1113},[958,5645,1658],{"class":968},[934,5647,5648,5649,5651],{},"This pattern will work when your application must retrieve the latest data from the endpoint (for example, an inbox). However, if the data that you’re fetching is dependent on the state of the application (assuming that the state is maintained through your URL and parameters), then you would be prefetching data even if the application’s state hasn’t changed since the user was last on the page. A better solution would be to fetch data only when the state of the application (",[944,5650,5422],{},") has changed:",[949,5653,5655],{"className":951,"code":5654,"language":953,"meta":954,"style":954},"\u002F\u002F Inside a router\ninitialize: function() {\n\n    this.cached = {\n        view: undefined,\n        model: undefined\n    }\n},\n\nindex: function(parameter) {\n    this.cached.model = this.cached.model || new Model({\n        parameter:parameter\n    });\n    this.cached.model.set('parameter', parameter);\n    this.cached.view = this.cached.view || new View({\n        model: this.cached.model\n    });\n}\n\n\u002F\u002F Inside of the model\ninitialize: function() {\n    this.on(\"change:parameter\", this.fetchData, this);\n}\n",[944,5656,5657,5661,5671,5675,5685,5693,5699,5703,5707,5711,5725,5745,5750,5754,5770,5790,5798,5802,5806,5810,5815,5825,5849],{"__ignoreMap":954},[958,5658,5659],{"class":960,"line":961},[958,5660,5353],{"class":1448},[958,5662,5663,5665,5667,5669],{"class":960,"line":985},[958,5664,5358],{"class":978},[958,5666,1126],{"class":968},[958,5668,1129],{"class":964},[958,5670,2913],{"class":968},[958,5672,5673],{"class":960,"line":991},[958,5674,1117],{"emptyLinePlaceholder":1116},[958,5676,5677,5679,5681,5683],{"class":960,"line":1004},[958,5678,3703],{"class":1022},[958,5680,5375],{"class":968},[958,5682,972],{"class":964},[958,5684,1480],{"class":968},[958,5686,5687,5689,5691],{"class":960,"line":1010},[958,5688,5384],{"class":968},[958,5690,3713],{"class":1022},[958,5692,1026],{"class":968},[958,5694,5695,5697],{"class":960,"line":1016},[958,5696,5393],{"class":968},[958,5698,5396],{"class":1022},[958,5700,5701],{"class":960,"line":1029},[958,5702,2023],{"class":968},[958,5704,5705],{"class":960,"line":1040},[958,5706,3647],{"class":968},[958,5708,5709],{"class":960,"line":1046},[958,5710,1117],{"emptyLinePlaceholder":1116},[958,5712,5713,5715,5717,5719,5721,5723],{"class":960,"line":1052},[958,5714,5413],{"class":978},[958,5716,1126],{"class":968},[958,5718,1129],{"class":964},[958,5720,1143],{"class":968},[958,5722,5422],{"class":1192},[958,5724,1196],{"class":968},[958,5726,5727,5729,5731,5733,5735,5737,5739,5741,5743],{"class":960,"line":1062},[958,5728,3703],{"class":1022},[958,5730,5431],{"class":968},[958,5732,972],{"class":964},[958,5734,3392],{"class":1022},[958,5736,5431],{"class":968},[958,5738,5440],{"class":964},[958,5740,1821],{"class":964},[958,5742,4087],{"class":978},[958,5744,982],{"class":968},[958,5746,5747],{"class":960,"line":1072},[958,5748,5749],{"class":968},"        parameter:parameter\n",[958,5751,5752],{"class":960,"line":1077},[958,5753,4282],{"class":968},[958,5755,5756,5758,5760,5762,5764,5767],{"class":960,"line":1083},[958,5757,3703],{"class":1022},[958,5759,5637],{"class":968},[958,5761,1858],{"class":978},[958,5763,1143],{"class":968},[958,5765,5766],{"class":997},"'parameter'",[958,5768,5769],{"class":968},", parameter);\n",[958,5771,5772,5774,5776,5778,5780,5782,5784,5786,5788],{"class":960,"line":1093},[958,5773,3703],{"class":1022},[958,5775,5462],{"class":968},[958,5777,972],{"class":964},[958,5779,3392],{"class":1022},[958,5781,5462],{"class":968},[958,5783,5440],{"class":964},[958,5785,1821],{"class":964},[958,5787,5475],{"class":978},[958,5789,982],{"class":968},[958,5791,5792,5794,5796],{"class":960,"line":1102},[958,5793,5393],{"class":968},[958,5795,1152],{"class":1022},[958,5797,5486],{"class":968},[958,5799,5800],{"class":960,"line":1107},[958,5801,4282],{"class":968},[958,5803,5804],{"class":960,"line":1113},[958,5805,1658],{"class":968},[958,5807,5808],{"class":960,"line":1120},[958,5809,1117],{"emptyLinePlaceholder":1116},[958,5811,5812],{"class":960,"line":1135},[958,5813,5814],{"class":1448},"\u002F\u002F Inside of the model\n",[958,5816,5817,5819,5821,5823],{"class":960,"line":1169},[958,5818,5358],{"class":978},[958,5820,1126],{"class":968},[958,5822,1129],{"class":964},[958,5824,2913],{"class":968},[958,5826,5827,5829,5831,5833,5835,5838,5840,5842,5845,5847],{"class":960,"line":1174},[958,5828,3703],{"class":1022},[958,5830,1155],{"class":968},[958,5832,2829],{"class":978},[958,5834,1143],{"class":968},[958,5836,5837],{"class":997},"\"change:parameter\"",[958,5839,1866],{"class":968},[958,5841,1152],{"class":1022},[958,5843,5844],{"class":968},".fetchData, ",[958,5846,1152],{"class":1022},[958,5848,2057],{"class":968},[958,5850,5851],{"class":960,"line":1179},[958,5852,1658],{"class":968},[929,5854,5856],{"id":5855},"jsdoc-functions-and-backbonejs-classes","JSDoc Functions And Backbone.js Classes",[934,5858,5859,5860,5865],{},"I’m a huge fan of documentation and ",[2253,5861,5864],{"href":5862,"rel":5863},"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJSDoc",[3503],"JSDoc",". I JSDoc all Backbone classes and functions in the following format:",[949,5867,5869],{"className":951,"code":5868,"language":953,"meta":954,"style":954},"var Thing = Backbone.View.extend(\n  \u002F** @lends Thing.prototype *\u002F {\n    \u002F** @class Thing\n     * @author Phillip Whisenhunt\n     * @augments Backbone.View\n     * @contructs Thing object *\u002F\n    initialize() {},\n\n    \u002F** Gets data by ID from the thing. If the thing doesn't have data based on the ID, an empty string is returned.\n     * @param {String} id The id of get data for.\n     * @return {String} The data. *\u002F\n    getDataById: function (id) {},\n  },\n);\n",[944,5870,5871,5887,5903,5914,5925,5935,5945,5952,5956,5961,5976,5988,6004,6008],{"__ignoreMap":954},[958,5872,5873,5875,5878,5880,5882,5884],{"class":960,"line":961},[958,5874,965],{"class":964},[958,5876,5877],{"class":968}," Thing ",[958,5879,972],{"class":964},[958,5881,2510],{"class":968},[958,5883,979],{"class":978},[958,5885,5886],{"class":968},"(\n",[958,5888,5889,5892,5895,5898,5901],{"class":960,"line":985},[958,5890,5891],{"class":1448},"  \u002F** ",[958,5893,5894],{"class":964},"@lends",[958,5896,5897],{"class":978}," Thing.prototype",[958,5899,5900],{"class":1448}," *\u002F",[958,5902,1480],{"class":968},[958,5904,5905,5908,5911],{"class":960,"line":991},[958,5906,5907],{"class":1448},"    \u002F** ",[958,5909,5910],{"class":964},"@class",[958,5912,5913],{"class":1448}," Thing\n",[958,5915,5916,5919,5922],{"class":960,"line":1004},[958,5917,5918],{"class":1448},"     * ",[958,5920,5921],{"class":964},"@author",[958,5923,5924],{"class":978}," Phillip Whisenhunt\n",[958,5926,5927,5929,5932],{"class":960,"line":1010},[958,5928,5918],{"class":1448},[958,5930,5931],{"class":964},"@augments",[958,5933,5934],{"class":978}," Backbone.View\n",[958,5936,5937,5939,5942],{"class":960,"line":1016},[958,5938,5918],{"class":1448},[958,5940,5941],{"class":964},"@contructs",[958,5943,5944],{"class":1448}," Thing object *\u002F\n",[958,5946,5947,5949],{"class":960,"line":1029},[958,5948,2803],{"class":978},[958,5950,5951],{"class":968},"() {},\n",[958,5953,5954],{"class":960,"line":1040},[958,5955,1117],{"emptyLinePlaceholder":1116},[958,5957,5958],{"class":960,"line":1046},[958,5959,5960],{"class":1448},"    \u002F** Gets data by ID from the thing. If the thing doesn't have data based on the ID, an empty string is returned.\n",[958,5962,5963,5965,5968,5971,5973],{"class":960,"line":1052},[958,5964,5918],{"class":1448},[958,5966,5967],{"class":964},"@param",[958,5969,5970],{"class":978}," {String}",[958,5972,2728],{"class":968},[958,5974,5975],{"class":1448}," The id of get data for.\n",[958,5977,5978,5980,5983,5985],{"class":960,"line":1062},[958,5979,5918],{"class":1448},[958,5981,5982],{"class":964},"@return",[958,5984,5970],{"class":978},[958,5986,5987],{"class":1448}," The data. *\u002F\n",[958,5989,5990,5993,5995,5997,5999,6001],{"class":960,"line":1072},[958,5991,5992],{"class":978},"    getDataById",[958,5994,1126],{"class":968},[958,5996,1129],{"class":964},[958,5998,1189],{"class":968},[958,6000,4204],{"class":1192},[958,6002,6003],{"class":968},") {},\n",[958,6005,6006],{"class":960,"line":1077},[958,6007,1231],{"class":968},[958,6009,6010],{"class":960,"line":1083},[958,6011,2057],{"class":968},[934,6013,6014,6015,6017,6018,6022,6023,6027,6028,6032],{},"If you document your Backbone classes in the format above, then you can generate beautiful documentation that contains all of your classes and functions with parameters, return types and descriptions. Be sure to keep the ",[944,6016,5358],{},"function as the first function declared, which helps when generating JSDoc. If you’d like to see an example of a project that uses JSDoc, check out the",[2253,6019,6021],{"href":6020},"https:\u002F\u002Fgithub.com\u002Fhomeaway\u002Fcalendar-widget","HomeAway Calendar Widget",". There is also a ",[2253,6024,6026],{"href":6025},"http:\u002F\u002Fgruntjs.com\u002F","Grunt.js"," plugin, ",[2253,6029,6031],{"href":6030},"https:\u002F\u002Fgithub.com\u002Fkrampstudio\u002Fgrunt-jsdoc-plugin","grunt-jsdoc-plugin",", to generate documentation as part of your build process.",[929,6034,6036],{"id":6035},"practice-test-driven-development","Practice Test-Driven Development",[934,6038,6039,6040,6045,6046,6051],{},"In my opinion, if you’re writing in Backbone.js, you should be following ",[2253,6041,6044],{"href":6042,"rel":6043},"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FTest-driven_development",[3503],"test-driven development"," (TDD) for your models and collections. I follow TDD by first writing failing ",[2253,6047,6050],{"href":6048,"rel":6049},"https:\u002F\u002Fgithub.com\u002Fpivotal\u002Fjasmine",[3503],"Jasmine.js"," unit tests against my models or collections. Once the unit tests are written and failing, I flush out the model or collection.",[934,6053,6054],{},"By this point, all of my Jasmine tests will have been passing, and I have confidence that my model functions all work as expected. Since I’ve been following TDD, my view layer has been super-easy to write and also extremely thin. When you begin practising TDD, you will slow down; but once you wrap your head around it, your productivity and the quality of your code will dramatically increase.",[6056,6057,6058],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":954,"searchDepth":985,"depth":985,"links":6060},[6061,6064,6065,6066,6072,6073,6074],{"id":926,"depth":985,"text":927,"children":6062},[6063],{"id":931,"depth":991,"text":932},{"id":1579,"depth":985,"text":1580},{"id":2214,"depth":985,"text":2215},{"id":3072,"depth":985,"text":3073,"children":6067},[6068,6069,6070,6071],{"id":3514,"depth":991,"text":3515},{"id":3550,"depth":991,"text":3551},{"id":3983,"depth":991,"text":3984},{"id":4180,"depth":991,"text":4181},{"id":4384,"depth":985,"text":4385},{"id":4391,"depth":985,"text":4392},{"id":4670,"depth":985,"text":4671,"children":6075},[6076,6077,6078,6079,6080,6081],{"id":4879,"depth":991,"text":4880},{"id":4891,"depth":991,"text":4892},{"id":5152,"depth":991,"text":5153},{"id":5339,"depth":991,"text":5340},{"id":5855,"depth":991,"text":5856},{"id":6035,"depth":991,"text":6036},"2014-04-22","md","\u002Fimages\u002Fblog\u002Ffeatures\u002Fbackbone-patterns.jpg",{},{"title":58,"description":60},"blog\u002Fbackbone-patterns",[16,17,51],"jrMxvAI-Nz0KpfjhjadvgMLgeQeLjHC4Sihv_LZftSc",[6091,6093],{"title":157,"path":158,"stem":6092,"children":-1},"blog\u002Fdevelop-mobile-apps-phonegap",{"title":877,"path":878,"stem":6094,"children":-1},"blog\u002Funits-for-css-font-size",1784954535515]