How to access Backbone Model properties in a Handlebar template - backbone.js

If there is a Backbone Model called Person, which has properties firstName, lastName. Usually, access to it is like person.get('firstName') and person.get('lastName').
How do I do a similar thing in a Handlebar template, where a person has been exposed to the context.

When you render the Handlebars template, you need to pass in the attributes of the model. The recommended way to do this is to call Model.toJSON, which returns a copy of the the model's internal attributes hash.
var template = Handlebars.compile(templateHtml);
var rendered = template({ person: model.toJSON() });
In the template you can access the context by the property name.
<span>{{person.firstName}} {{person.lastName}}</span>

Actually I've so many places with .toJSON so I've developed a Handlebars modification to handle Backbone Models:
https://gist.github.com/4710958
It will check if a value is instance of Backbone.Model and if it is it will invoke the .get() method.
Backbone.Model should be global in order to use it.
{{ user.address.street }}
Will be parsed as:
user.get("adress").street

Related

AngularJS performance when using ng-repeat with big objects (not long arrays)

I just learned about $scope.watch here https://stackoverflow.com/a/15113029/2241256.
It says that everything that is used in the view is monitored by angular. So I am wondering what happens when I am using an array containing big objects in a ng-repeat?
Say each object has an attribute: 'name', which is the only thing I use in the list. Will angular still look for changes in the whole object or just look at the 'name' attribute of each object?
AngularJS watches just that name property of objects because of showing on view. By the way, if those values which is name property don't need to be directly updated, you can use one-way data binding by adding :: before of variables. Like; ng-bind="::object.name". If you do this, AngularJS doesn't watch that variable of your object. Don't worry. If you update your array which contains all of this objects, AngularJS will update those name attributes because of updating array.
You can read this page of docs for one-way data binding.
Just the 'name' attribute.
Only what's used inside of a template (between {{ and }}), or registered manually ($scope.watch('myVar', function () { ... })) is watched for changes

Using only this in controller get $emit in Angular

Can we use only this in controllers, without $scope?
In some cases of course yes, i know... But...
If we need $emit, $broadcast and some other angular features, which we can find only in scope? Can we get it in this may be, or some other ways to get it?
As far as I'm aware there are some special cases like $emit etc which you have to use $scope and can't use this.
When you create a controller in this format :
angular.module('myModule').controller('myController',['$scope',function($scope){
//controller code here
}]);
the function that you are passing is basically a constructor for the controller object
so when you write a code like this :
angular.module('myModule').controller('myController',['$scope',function($scope){
this.myObject = { key : value};
}]);
you are basically making myObject a property of the myController object
Controllers are basically used in angular.js to fascillitate communication between your view( which are handled by directives ) and services( which take care of the buisness logic )
To enable that you can use the dependency injection angular provides and insert the $scope object into your controller as shown above
when you instantiate a controller using ng-controller="myController" a new scope object is created to be used with your controller object. the $scope object that you have passed as an argument to the constructor function of the controller has the newly created scope.
Here is an excerpt from angular documentation :
The properties contain the view model (the model that will be presented by the view). All the $scope properties will be available to the template at the point in the DOM where the Controller is registered.
so basically whatever properties you attach to the $scope object only will be avalaible to be manipulated in DOM
any property you attach to this wont be available in the DOM. for example :
this is you angular configuration :
angular.module('myModule').controller('myController',['$scope',function($scope){
$scope.name = 'kiran'
this.message = 'hello world';
}]);
This is your html :
<p>{{name}}</p>
Output will be : kiran.
if you had tried : <p>{{message}}</p> instead it will throw an error.
only the scope object contains properties like $$watchers which is a list of all the variables that are watched on the current scope, $watch API,$on API for event handling and so on.
so you cannot use this to leverage those properties.Hope this clears stuff up.

How to extend $scope globally?

I would like that all my $scope objects contain a specific helper method that I use to retrieve data like $scope.getData('member.submember.othermember') otherwise I would have to do $scope['member']['submember']['othermember'].
The idea is to add this .getData method to all the created $scope objects by default.
Is there any extensibility point where I may add that?
Angular scopes use JS prototypal inheritance, it is possible to add custom method to all scopes (in addition to existing $ methods) with
$rootScope.constructor.prototype.$getData = function () { ... };

AngularJS - ngView scope?

I'm using ngView's to load content on demand.
What I don't quite get is when is the controller for each view created?
I have the same controller assigned to a few of my views, and they seem to share data between them. yet my impression is that the controller is recreated each time the specific view is shown.
So how does it work?
When you define a controller in your JavaScript using .controller(), you defining a class, not creating an instance of an object.
Colin Moock defines the difference this way: an Object is like an airplane, it can perform actions like fly() and has properties like maxPassengers. A Class is like the blueprint on how to build that airplane, from which you can make infinite airplanes. Amazing! You can watch Colin Moock's whole explanation right here if you want: http://tv.adobe.com/watch/colin-moocks-lost-actionscript-weekend/object-oriented-programming-overview/
Every time the view is loaded, a new Instance of your controller Class is created. Most Angular.js controllers have a capitalized name like Dashboard or Contacts because they describe a Class.
So the answer to your question is a new instance of your controller is created every time your view loads.
It turns out that when using a factory for your model and injecting the model into the controller, then you can keep state when you change views.
I used a factory for one of my controllers and "new FooModel()" inside another controller, thus two different behaviors on the views using the two controllers.

Cakephp - Overriding model method from controller

I need to override & add methods in a model invoked by a controller. I don't want to write anything inside Model class file because it's used by other controllers too. Methods are like pagination() and find(), can I do it from inside a controller?
CakePHP behaviors are mixins. They add methods to a model, which is what you are looking for.
It sounds like dynamically attaching a behavior to the model would get you the outcome you need.
Looking at Model::__construct(), I can see that it calls $this->Behaviors->init($this->alias, $this->actsAs);.
You may be able to call it again after the model has been instantiated to attach different behaviors (ie. $this->MyModel->Behaviors->init('MyModel', array('MyBehavior'));).
In fact, a closer look reveals that $this->MyModel->Behaviors is an instance of BehaviorCollection. As such, you can use the attach() method.

Resources