when to use defaults vs the initialize constructor on a model - backbone.js

So, I'm trying to learn how to use Backbone and I keep switching back and forth between using the defaults object and the initialize method. If I use the method, it's with "this.set()" to set attributes, etc. Otherwise those attributes are set in the default object.
I've looked around on google and I can't seem to find a recommended way or "common" pattern of when to use defaults or when to use initialize. I can make my code work both ways and both yield an object with the desired attributes, but it bugs me because i'm unsure if i'm using it incorrectly.

You would use the defaults object for all "static" data as you can only define them once for a model class. You will need the initialize method if you have to add dynamic per instance properties. For example:
initialize: function() {
this.set({displayName: this.get('firstname') + this.get('lastname')});
}

Related

SilverStripe: Creating form fields statically and via the 'new' keyword

I've been trying to find some info on difference between instantiating form fields through static method and the new keyword. Can somebody tell me what are the practical implications, limitations, between new MyFormField and MyFormField::create() esp. with regards to SilverStripe
Using the create factory method would check for overloads (set via Object::useCustomClass()) and return an instance of the custom class in that case.
This method first for strong class overloads (singletons & DB
interaction), then custom class overloads. If an overload is found, an
instance of this is returned rather than the original class. To
overload a class, use Object::useCustomClass()
So using the create method rather than instantiating the Object yourself would provide a possibility to overload the used Class without altering the code.
see
http://api.silverstripe.org/3.1/class-Object.html#_useCustomClass
http://api.silverstripe.org/3.1/class-Object.html#_create

CakePHP UnitTest a method which calls another model

I'm writing a variety of Model Tests in CakePHP (PHPUnit)
In TravisCI, I get something like: "Base table or view not found: 1146 Table 'test.events'
In Cake's test runner I get an assertion failure.
The problem I am having is there are methods in my ModelClasses that I am trying to test which call other models with App::uses. For example:
Method on User model:
public function getOtherData() {
App::uses('Event', 'Model');
$this->Event = new Event;
return $this->Event->find('all');
}
And the test:
public function testGetOtherData() {
$result = $this->User->getOtherData();
$this->assertTrue(!empty($result));
}
Note the above example is just that. An example, simplified to show the problem. I understand that the above example has better 'cake' ways of doing it.
Also, I am using defining required fixtures and they work just fine. (I know this by another method in the model which uses a join in the find, instead of App::Uses())
EDIT:
The code when run works, BUT the UnitTest is looking for the other models data (When using App::uses) in the default database, and not the test database. Why doesn't it use the test database? Am I missing something?
LAST NOTE
Using App::uses() and then instantiating the class will work at runtime. But during testing it will fail, as it attempts to use the default database connection, instead of the test database connection.
Per the selected answer, rather than using App::uses, Cakes built in class registry, ClassRegistry::init('Model', true);, you can include a Model from inside another model method.
It's not generally a good idea to instantiate an object in the middle of your functions using the new statement. This is why -- there's no way to block or redirect that call. Also, it's not necessarily easy to get the right parameters to the object's constructor when it's in the middle of another function, so it's best to keep that code separate.
The right way to do this is to use a different method call to get your object. If you use Cake's ClassRegistry::init() to create model objects, they should use the test database.
If you need to create other non-Cake objects, it's best to create them using some other function, e.g. $this->fetchMeOneOThemEventThingies(). Then, during testing, you can mock out that function and have it return something else. Or, you could use some other DI container like pimple, which will take the same role as Cake's ClassRegistry.
If you need a mock model object for testing, be sure to pass the appropriate arguments to the model's constructor as the third parameter to getMock(), or it may use the production database.

backbone.js accessing model attributes within model - this.attribute VS this.get('attribute')?

From my understanding the attributes of a Backbone.js model are supposed to be declared as somewhat private member variables by saying
this.set({ attributeName: attributeValue })
// accessing the value
this.get('attributeName');
But when I am writing functions whitin the actual model it seems much simpler to say like this:
this.attributeName = attributeValue;
// accessing the value
this.attributeName;
Also I would assume that the latter version would be faster to process since it doesn't go through backbone.js's event management.
So I was wondering how you pros do with attributes that are primarily used internally in the model. These are the attributes that one would actually want to be a bit shielded from the outside so having them exposed like in the latter example maybe isn't right still. When I have been looking at examples for the backbone.js view which doesn't have get and set methods it seems fine to do like in the second example. So is there any nice rule of thumb when to use get/set(attribute) or this.attribute when coding within the model? Or maybe an example of a model that makes this clearer?
When to use model.get(property) and model.set(...)
You should use get and set to access the model's data. This means any attributes that are part of the model's serialized representation that is retrieved using fetch and persisted using save.
When to use model.attributes.property
Never.
You should always use get, and especially set, instead of accessing the model.attributes object directly, although I've seen conflicting opinions about this. I believe there is a contract between a model and it's consumers, which guarantees that the consumer can be notified of any changes to the model's data using the change event. If you modify the internal attributes object directly, events are not sent and this contract is broken. Backbone events are very fast, especially if you don't have any listeners attached to them, and it's not a point that benefits from over-optimization on your part.
Although accessing the attributes directly instead of get is quite harmless on it's own, it should be avoided so the attributes object can be considered totally, completely private.
If you absolutely need to prevent some change triggering events, you can use the silent:true option: model.set({key:val}, {silent:true}). This does break the aforementioned contract, and even Backbone's own documentation gives the following caveat:
Note that this is rarely, perhaps even never, a good idea. Passing through a specific flag in the options for your event callback to look at, and choose to ignore, will usually work out better.
When to use model.property
Any properties which are not data, i.e. temporary state variables, calculated properties etc. can be attached directly to the model entity. These properties should be considered temporary and transitive: they can be recreated upon model initialization or during its lifetime, but they should not be persisted, whether public or private. A typical naming convention is to prefix private properties with the _ character as follows:
this._privateProperty = 'foo';
this.publicProperty = 'bar';
Never is an incomplete answer.
Sometimes you want access to the collection of model attributes - whatever those attributes might be. Consider a utility method to perform calcs on attributes, format them for output, etc.
A convenient way to do this is to access model.attributes
Consider one alternative, below:
var attributesNames = ['foo', 'bar', 'baz'];
var attributes = _(attributesNames ).map(function(attr) { return model.get(attr); });
callSomeUtilityMethod(attributes);
Two problems:
We've introduced coupling in the "attributeNames" collection. What if that list changes?
We've lost the association of name/value. We could rewrite the map above, but it becomes more work.
In this scenario, it's much more convenient to do something like this:
callSomeUtilityMethod(model.attributes);

extjs - dot notation to bracket {} notation?

not sure that that is a good title ...
I can get code behind a button to:
TabBar.activeTab.setTitle("New Tab");
but I need to do something like:
TabBar.activeTab.items = { title: "New Tab"
};
so I can eventually automate several tab properties in a loop:
TabBar.activeTab.items = { [key]: [value]
};
Am I correct in thinking config and items can only be used on construct()? Is there a way of doing the above? tia.
It depends on the implementation of the component and config property in question whether it can simply be set or requires a method call to be applied.
You are correct that in ExtJs many config properties are interpreted at construction time. Some are interpreted at render time. Once an Ext.Component is rendered almost all properties require an explicit method call to be applied correctly.
In general, I recommend to always use a method call to change a property after construction time if available in order to not break the inner workings of the component. If you look at the implementation of Ext.panel.Panel#setTitle you can see that there is a lot of stuff going on under the hood, e.g. event firing, etc.
ExtJs 4 configuration
Ext 4 introduced an explicit 'config' mechanism that might serve your purpose. However, my understanding is that most ExtJs components are not (yet?) using it.
Check out '2. Configuration' in the ExtJs Class System Guide
Create objects from xtype/config literals
If you want to add new components to a container (e.g. tabs to a tab panel) it would be rather easy to accomplish.
Use Ext.ComponentManager#create (see [docs][2]) to create an actual component object/instance from your config literal.
Ext.container.Container#add actually calls this method internally, so you can simply pass config objects to the add method.
If you want to remove or add tabs to a panel, there is now way around calling the proper methods.
applyConfig()
Of course you could always implement your own applyConfig method that supports changing certain component configuration properties at runtime by 'translating' the config into the proper method calls.

View which manages some generic variable object with Prism

I'm working with Prism and I have a view which will manage some variable entity objects.
E.g.: Now I'm managing a User, but later I would manage a Customer using the same view (I already have the solution to achieve it ... link 1 - link 2).
This object (or the object type) to be managed must be declared and passed by me.
In a common way, I could pass the object type through a parameter on the constructor, but as I'm using Prism and I don't directly use the constructor of the Views or ViewModels.
Here's a snippet of how I currently "invoke" my views:
var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
var viewUri = new Uri("MyGenericView", UriKind.Relative);
regionManager.RequestNavigate("AreaTrabalho", viewUri);
The problem is: I can't pass a parameter. Is there a way of passing that parameter or an alternative way of doing this (without a kind of ugly hack)?
You can implement INavigationAware on your VM's and pass parameters inside query string in your regionManager.RequestNavigate call

Resources