Why are there getters and setters with Backbone models? There are no private/protected attributes, so the getters and setters are a bit useless for encapsulation. I know they are useful for the validations, but other than that, what are their utility if we can bypass them?
set is not simply doing below thing.
this.attributes["key"] = value;
If you bypass it, you will miss all other functions that it is doing here.
Currently it is doing 2 functionalities.
1.It is calling _validate method before value is assigned to attributes. refer this.
2.It triggers change event if you listen for an attribute change.
If they add further functionalities in future, you may lose them, if you by-pass set.
Related
What are the advantages and disadvantages of the following 2 lines of code? I don't understand why there are 2 different ways to do the same thing.
this.listenTo(app.Todos, 'change:completed', this.filterOne);
app.Todos.on('change:completed', this.filterOne);
Also when using .on, how do I determine is the default context?
listenTo is the newer and better option because these listeners will be automatically removed for you during stopListening which is called when a view gets removed (via remove()). Prior to listenTo there was a really insidious problem with phantom views hanging around forever (leaking memory and causing misbehavior) because view methods were referenced as event listeners on models even though the view instances themselves were long gone and no longer in the DOM.
If you want to read the back story for listenTo, search the backbone github repository for listenTo and read through some of the longer issue discussions.
As to the default context, several things can end up bound to this:
if you do the binding via this.listenTo, it will always be the view instance (pointed out by Wim Leers in the comments)
without this.listenTo, the story gets complicated
For misc events, it will be the global object (best to avoid this)
for DOM events, it will be the source element just like in regular DOM event binding
If you provide an explicit context (the 3rd argument to foo.on), backbone will use that (thus this is a more robust approach)
If you use the ECMA standard function () {//your event handler}.bind(this), you can also manually control the context (also recommended)
As #mu pointed out, _.bind or $.proxy are available alternatives to ECMA function.bind
For backbone views, doing this.bindAll('onClick', ...) will ensure the view instance is the this context when any view methods are used as event handlers
any events wired up by using the view's standard events property will get bound for you automatically to the view instance by backbone (this is belt & suspenders with bindAll)
So to summarize into some guidelines:
use the events property whenever possible as it is concise and correct
use this.listenTo for all bindings to models and collections
any additional bindings remember to bind the context reliably using your preferred method. I usually use ECMA Function.bind because hey, standards, but there are several good options here.
With listenTo, the object whose events you want to listen to is passed as the first argument. In the case of on, it is actually a method on that object.
The advantages of listenTo over on are:
The listener keeps track of all the event handlers, making it easier to remove them all at once when needed.
The callback’s context is always set to the listener itself.
DependencyObjects can have SetValue() available and most (if not all) of WPF's stock UIElement derived controls contain DependencyObject properties than can be set via SetValue. Sometimes it is practical to do code-behind in a WPF application. Below produces similar result. But which one is better?
<TextBlock x:Name="myTextBlock" Loaded="myTextBlock_Loaded"/>
And setting the Text property can be done in two ways.
myTextBlock.Text = "foo";
OR
myTextBlock.SetValue(TextBlock.TextProperty, "foo");
Maybe the difference is trivial but I'm curious whether there is an advantage of using the one over the other.
There is a slight performance boost* in the second, as the implementation of TextBlock.Text set is actually return this.SetValue(TextBlock.TextProperty, value);.
However it should be noted that it is possible to get the second implementation wrong, for example you could end up typing
myTextBlock.SetValue(Grid.ColumnProperty, "foo");
Which would compile, but likely not run (or at least not give the expected result).
Further, the former will give you type-safety that the later would not give.
*"This performance boost" should however be JITed away.
Dependency properties with actual properties are essentially conveniences to get or set those properties through code. All dependency properties for all dependency objects are backed by a "dictionary" of key/values. Those values are accessed through the GetValue() and SetValue() methods.
What is "better" all depends on how you intend to use the properties. All builtin controls define properties to make it easier to initialize the objects through code. It would be far messier if you tried the same using the Get/Set methods.
But don't look at it in terms of what is "better," you'll get nowhere thinking in that way. Both are necessary. The dependency properties are how you get/set observable properties of dependency objects. Making those properties accessible with corresponding properties makes using your code easier.
If you don't need to access these dependency properties through code, then I suppose you could argue that the properties are not needed, but then nobody would want to use it.
I have created a Backbone.Collection of (say) ModelA and I am trying to listen to changes to a specific attribute of those models. This is straightforward, ...on('change:attr1'). This fires the event exactly when it needs to. The problem however is when that attribute is another model (ModelB) which has its own attributes. If an attribute of ModelB is changed, the collection won't be able to capture that event (and this is right, the attributes of ModelA never changed, the "attributes of attributes changed").
An idea is to wire-up listeners from ModelB to ModelA and then to the collection. This could work, but we are now adding a lot of listeners to build this chain of events. I also suspect that it will be a pain to unbind those listeners when we don't need them.
So is there a better way (or alternative) way of achieving this? Any feedback is appreciated.
Thanks
I think the cleanest way is to forward events through the parent model. Look at my example: http://jsfiddle.net/w8n9erqo/
But also you can override collection methods _addReference and _removeReference to add custom event binding logic. http://backbonejs.org/docs/backbone.html#section-118
Hope this helps
Pretty much it summarizes my problem here:
Double check - does it ever make sense to have internal viewmodel class?
I have controls.DLL and I'd like to keep this custom control bindings and viewmodel's internal. However, this doesn't seem to be possible.
How do you get around that? The only way I see it - don't use bindings..
Why do you have a view model for a custom control? I assume you're assigning the view model object to the DataContext property, but this is almost always a mistake: the DataContext should be available to consumers to use and abuse as they please. Stated another way, what happens if a consumer of your custom control explicitly sets the DataContext? It sounds like your control will stop working and throw a bunch of xaml binding errors.
A custom control is inherently lookless. There is no model or view model, just a view. That view is the .cs file. You supply a default look via your themes/generic.xaml file, but consumers should be able to supply their own template. If you're tying them to a view model, they also need to know how to create a view model instance and all of its dependencies. You've just created highly coupled code. DI containers can loosen the coupling, but that just downgrades the relationship between classes from "coupled" to "related". I say, why do consumers even need to know that information?
A better approach is to provide all of the properties for your control as dependency properties. Then your generic.xaml can provide a control template that uses the more efficient TemplateBinding to bind properties/objects to your control. If you need to populate these dependency properties from a business object, expose another dependency property of type IBusinessObject and set the derived values in that object's PropertyMetaData changed handler. If your IBusinessObject type contains a property which is yet another class which implements INotifyPropertyChanged, you should probably (1) rethink your object graph or (2) create a Bnding object in code using the subclass.
I think following all of the above advice will eliminate the problem about which you're concerned plus the other problems as well. Leave the view models to the UserControls. And yes, this is why custom controls are a MASSIVE headache. Doing them right is fairly involved.
Try protected internal. I suppose this should work. Although I don't think its good idea to have the ViewModel not public at all, cause one of the purposes of it is to be able to define several Views against the same ViewModel, which may come from different assemblies.
So I think I understand what a dependency property is and why we need them - they are properties managed by the Silverlight/WPF libraries such that the runtime can have some control over how they are set, enabling them to do such things as giving animations precedence over other types of requests on the properties and other nifty features.
My question is, how does the framework know how to do this? If dependency properties are always accessed through their getters/setters on their parent objects (which defer to GetValue() and SetValue()) then how can the dependency repository* know who is making the request in order to prioritize it?
Sorry if this is a very basic/obvious question.
* Is there a name for the container that manages dependency properties? I'm thinking the DP registry, considering we have to register them?
Yes, there is a registry but its all hidden. And No, dependency properties are not at all set via Getter and Setter instead DependencyObject has methods called GetValue and SetValue where you actually pass handle to your dependency property. Assume your DP has registry and it has dictionary and handle to your DP (the DP object you get after registering) is key.
This way, registry knows when and what to modify and what to update and to whom it needs to send notifications.
You can use reflector to explore .NET's internal, you will get idea that every DP needs to be registered by calling DependencyProperty.Register then only you can use it.