#**************************# #********* Level 1 ********# #**************************#
#MODEL class TodoModel Backbone.Model.extend
todoItem= new TodoModel({title: “You Can Set Attrs here when createing and instance”})
#VIEW class TodoView Backbone.View.extend
render: ->
some_html= "<h1> Hello From BackBone</h1>"
# or if you wanted to poplate hmtl with something more
#dynamic some_html couuld be
# some_html= this.model.get('title') => "You can set Attrs..."
$(this.el).html(some_html)
# This code says for what ever view instance you have created. find its el
#Tag and inside it populate it with "some_hmtl"
# LOGIC/MISC todoView= new TodoView({ model: todoItem}) #Note it takes in instance of model todoView.render() #This will populate this instance with the starte some_html console.log(todoView.el) #-> This would show you the populated el for this item
#Basic Getter and Setter Commands todoView.get(‘title’) #=> “You Can Set Atters Here” todoView.set({title: “The Title attr has now been changed”}) #=> Setting
#ADDING HTML TO DOM
todoView.render() #this populates the todoView currently empty el (div by default)
$('#id-on-the-page').html(todoView.el) #this takes the now populated (compliments of .render()) and appends it to the DOM
#InputWay Summary
1) In Main View create an instance of the Router class 2) The init method on the router class initalizes a new instance of the view 3) When the view is initalized it calls the render function on the new instance which populaes this.el 4) When a new view is initalized it also calls a 'position' function which then places the renderd html on page. This Creates The basic html for the user to now interact with
# GotChats On Events
For events the View Only watches what is INSIDE ITS .EL, SO ANY EVENT LISTNERS TAKING PLACE OUTSIDE WILL NOT FIRE #**************************# #****** Level 2 Models ****# #**************************#
class UserModel extends Backbone.Model
userInstance= new UserModel(name: “Greg”)
userInstance.url = ‘/user’ # tells url to get JSON //This is not the gold standered USE Restful URL in Model CLass user.fetch() #=> {name: “Greg”} populates the model user.get(‘name’) #=> will return Greg
##Redfine User Class With RESFULROUES class UserModel
urlRoot: '/users' # The Eqlivent of a Rails App resoruce
# Console Session userInstance= new UserModel(id:1) # this will create a new instance model that holds information from user 1… But it is not populated yet… userInstance.fetch() #=> Much better.. now we have a Populated JSON object with GET USER/1 userInstance.get(‘name’) #=> “Greg” userInstance.set(name:“Changed”) userInstance.save() #=> Sends information back to DB userInstance.get(‘id’) #=> If the user was successfuly saved to the DB then they will have an ID, else ID will be nil
save_me_here= userInstance.toJSON() #=> This will stroe the user Instance JSON in the defined var “save_me_here”
userInstance.destory() #-> Obvi kills off any user DELETE/user/2 userInstance.get(‘id’) #Should now error out
## Createing a User
user= new UserModel(name: "Save me") user.save #=> submits a post request which by default in rails is handled by create controller ** need rootURl Defined in Model Class
# Model Layer Defaults Events
class UserModel extends Backbone.Model
defaults:
name: "No Name was set so we will put this here by default"
userInstance.on(‘event-name’, someFunction) #Use listenTO over .on because listenTo is like destory vs delete. Listen to will take away event listens whern view is removed
# These events would be defined in the view with this.model.on @.model.on
userIstance.trigger(‘event-name’)
# MODEL EVENTS
'change' change:attr destroy sync error all #any event is triggerd userInstance.off('event-name', someFunction) userIstance.set(name:'change name', silent:ture ) #set attr without triggering an event #**************************# #****** Level 3 Views *****# #**************************#
class UserView extends Backbone.View userView= new UserView console.log(userView.el) #=> <div></div> this is the tagName
class UserView
tagName: "li" id: "user-view" className: "users-view" # all of this will change the userView.el
#Useing Templates class UserView
template: JST['template/index']
render: ->
attrs= @.model.toJSON #=> will render all attribtes
this.$el.html(this.template(attributes))== @.$el.html(@template(attrs)) # this will pass content to template you can then call diff attrs in the template
# for example <%= name %> or <%= age %> would all be avaliable in the template if entire JSON object is pased
#DOM events in views class UserView
event:
'click h3' :'someFunction' #this event is scoped to the view so any h3 clicked on page outside template will not fire!
'dblick' :'someThing' # no elemet specifed will apply to entire view
someThing: ->
alert(@.model.get('title')) #gets the title from the model assoicated with this view
#**************************#
#**Level 4 Models & Views*#
#**************************#
#Updateing Model when View Changes
class UserView
events:
'change input': 'toggleStatus'
toggleStatus: ->
if @model.get('status')==='pending' # this is alot of model logic in View and can be refactored!
@.model.set(status: 'approved')
else
@.model.set(status:"pending")
## Refactor OF above
toggleStatus: ->
@.model.toggleStatus() #calls model function
class UserModel
toggleStatus: ->
if @.get('status')=='approved' #this keeps model logic in model!
@.set(status:'approved')
else @.set(status:'pending')
@.save();
#If you only call render at end of toggleStatus and update the dom when view is changed. it does not account for the possibilty of updateing that model
# attr somewhere else in your app. Therefore it is best to put your model listeners in your model but in the views like so...
class UserView
initialize: ->
@.model.on('change', @.render, @) #thrid this required to specify context
#QUESTION HOW TO KNOW WHEN TO US@E THE THRID THIS???
@.model.on('destory', @.remove, @)
remove: ->
@.$el.remove()
render: ->
#**************************#
#**Level 5 Collections*****#
#**************************#
class UserCollection extendsBackbone.Collection
model :UserModel # this is required it is the MODEL CLASS
url: '/users'
userCollection= new UserCollection()
# collection instance methods
.length # returns number of models in collection
.add(userCollection)
.at(0) #=> returns first
.get(1) #=> returns instance by id
.remove(userCollection) #removes an instance
userArray= [{name: "user 2"}, {name: "user2"}, {name: "user3"}]
.userCollection.reset(useArray) #reset will add each item in an array
# POPULATEING A COLLECTION VIA SERVER
class UserCollection
url: '/users'
userCollection.fetch() #=> Get/users. This makes a get request to users#index and will return
#COLLECTION EVENTS
userCollection.on('reset', doThing) # reset fires anytime tecth or reset it called!
userCollection.on('add', doThing(userModel)) #> both add and remove take an argument
userCollection.on('remove', doThing(userModel))
userCollection.fetch(silent:true ) #will not trigger event listenr for reset
uuserCollection.off('rest', doThing)
#Model Events In a collection
.change
.change:attr
.destroy
.sync
.all
Iteration
.map (user) -> #new mutated array
userCollection.filter (x) -> #new array with only items that return ture
x.get('name')==Greg
userCollection.forEach (x) ->
#You Can init a collection with the init of the View!
class UserView
initialize: ->
startCollection()
startCollection: ->
userCollection= new UserCollection(model : userModel)
#InputWAY of userCollection.fetch()
1) this makes a get request to 'users#index', the index controller looks like the following
def index
@users=User.all
respond_to do |format|
format.json {} # This formation Json looks for a index.rabl file( from the rabl Gem) in users viwes(rails)
end
end
2) in the Rabl file you specify the json you would like to parse to the page with the follwoing syntax
collection @users
attributes :id, :name
#*******************************#
#**Level 6 Collections & Viwes**#
#*******************************#
#model instance and view instance has one to one realationship
# a colllection view has many views through models. In other words, a collection view does not render any
# of its own html. It delgates to each model which then call its own view
class UsersView extends Backbone.View
usersView= new UsersView(collection: usersCollection) #.collection now ref usersCollection
class UsersView
initalize: ->
@render()
render: ->
@.collection.forEach (user) => #use of Fat Arrow to provide correct context `
userView= new UserView(model: userInstance)
@.$el.append(userView.render().el) #calls the render() function on the userInstance View
# Example of Collection Views
@collection.each (model) => addOne(@)
addOne:(this)->
todo = new TodoView( model: model)
this.$el.append todo
a =[1,23,4,5]
_.each a, (n)=>
console.log n
_(a).each (n) =>
console.log n
# removeing an item from a collection does not destroy the item
how to remove steps
class UsersCollection
initialize: ->
@.on('remove', @.hideModel)
hideModel: (model) ->
model.triger('hide')
class UserView
initialize: ->
@.model.on('hide', @.remove, @)
#Input List Steps 1) create new instance of viewCollection in router pass in collection: App.ReadingCollection 2) On init of view create new instance of ReadingCollection passing in model: UserModel
3) on init of ReadingsCollection call this.fetch() #=> Populates the collection