I'm recently started playing with Backbone.js. I want to apply custom validation mechanism to my model classes and I decided to go with mixin classes. Now the question is it a good idea to attach the mixin to the Backbone.Model class like below,
_.extend(Backbone.Model.prototype, MyApp.ValidationMixin)
or can I create a base model AppModel from which all the application models extends and I'll attach the mixin to the base model.
var AppModel = Backbone.Model.extend({});
_.extend(AppModel.prototype, MyApp.ValidationMixin)
Is there any problem I'll face if I go with the first approach?
In general, the first approach is OK for this specific case (adding a Validation Mixin to the Backbone Model) but your validation Mixin may get erased by other libraries doing the same (it's sometimes hard to 'pick and choose' the functionality of additional Backbone libraries).
The second approach is safer and is the usual recommended approach as can be seen in various Backbone's app boilerplates.
Both are technically the same, as long as you live in your own little "app bubble".
Related
I am working on a ClojureScript wrapper for qx.mobile and would like to programmatically build a cljs type hierarchy mirroring the qx class hierarchy.
Is there a way to get all the subclasses of a qooxdoo class?
How about a programmatic way to query the superclass of a class?
I am already putting qx.Class.getProperties to good use.
Thx, kt
The programmatic way of getting the superclass of a given class is documented at http://demo.qooxdoo.org/current/apiviewer/#qx.Class
<classname>.superclass
or getting the name of the superclass as a string
<classname>.superclass.classname
which means that e.g.
qx.ui.core.Widget.superclass.classname
will return the string "qx.ui.core.LayoutItem".
Regarding the programmatic way to retreive all subclasses of a class:
This is currently not possible without iterating the whole class hierarchy/tree and testing the objects against being subclasses of the given class.
We discussed at https://gitter.im/qooxdoo/qooxdoo that it maybe would be usefull to create an array for each class holding the subclasses. This could be added to the code of the private method __createClass in qx.Class.
We would like to encourage everyone who needs this (or other) functionalities to join us on https://github.com/qooxdoo/qooxdoo/ and help extending qooxdoo by creating a pull requests. Thank you.
After digging arround a bit in qx.Class we decided to implement a method qx.Class.getSubclasses which returns a hash object with all subclasses of a given class.
var subclasses = qx.Class.getSubclasses(qx.ui.core.Widget);
gets all subclasses of qx.ui.core.Widget.
Landed in qooxdoo master with commit https://github.com/qooxdoo/qooxdoo/pull/9037
I'm working on an analytics-like dashboard with heavy data. Obviously waiting for all this data to come in isn't a good idea as it would increase load-times beyond acceptable lengths. My idea is to progressively add parts of data when certain Controllers instantiate a model. I imagine it'll end up looking something like this:
class List.Controller extends Marionette.Controller
initialize: (options) ->
{ model } = options
model.fetch( something here ) unless model.get('data')
#showData model
getDataView: (model) ->
new List.Data {model}
showData: (model) ->
dataView = #getDataView model
App.mainRegion.show dataView
I was wondering if someone has experience with this, and what a good strategy would be for what to pass into the fetch call and how to structure that...
Edit: to clarify, I'm looking for a scalable strategy to load more data for a model based on a get-param or a different endpoint when my app needs it. Should this be handled by methods on my model or by passing stuff into fetch for example?
The "standard" way is having a pageable collection, such as Backbone Pageable
Then you can have a CollectionView or CompositeView which will handle most of the work for you.
I have a small calendar widget-type thing on many pages throughout my site. The goal is for it to retrieve events from X category that fall between Y and Z dates.
My assumption (I'm new to CakePHP) was that I should create a component, and have it do the query. Something like this:
class CalendarComponent extends Object {
var $uses = array('Event');
function getEvents($category = null, $date = null, $limit = null) {
$events = $this->Event->find('list', //conditions to get correct events
return $events;
}
}
BUT, according to this CakeBook page:
To access/use a model in a component
is not generally recommended
So - where would I store this logic / model call if not in a component? I've admittedly not used a component yet (or not created one anyway) due to lack of really understanding how I should use them - any snippet of advice on this is also VERY welcome.
Great question in my opinion and I imagine one that comes up quite often. I was actually dealing with a similar problem where I wanted some site-wide data gathering or functionality shoved into a component.
The first thing to keep in mind:
The book is a guideline.
These 'rules' aren't rules. If there's a good reason for breaking the rule and you understand why the rule is being broken then break the damn thing! Cake itself breaks this rule quite often.
Core components that require/use models:
Acl
Auth
Sessions (fairly positive you can save session data to a model)
So, clearly there are use cases where you need to use a model inside a component. How do you do it though?
Well, there's a couple different ways. What I wound up going with? Something like this:
<?php
ModelLoadingComponent extends Object {
public function startup($controller) {
$controller->loadModel('Model');
$this->Model = $controller->Model;
}
}
?>
That's it! Your component is now setup to use $this->Model...just like you would in a controller.
Edit:
Sorry, to clarify: no, you don't have to setup a new component to load models. I was showing an example for how you could load a component in any model. The startup function I used is a component-specific callback, there's a whole slew of them http://book.cakephp.org/view/998/MVC-Class-Access-Within-Components. These callback methods make components a lot easier to work with. I highly recommend looking at this part of the components tutorial if nothing else.
If you were working inside an AppController object you could call $this->loadModel() but we aren't working an AppController! We're working with a component, really an Object. There is no Object::loadModel() so we have to come up with a different way to get that model. This is where $controller comes into play in our startup callback.
When the startup method is invoked by Cake it will pass the $controller object it's working with on this dispatch as the first parameter. With this we're able to access controller methods...like loadModel().
Why do we do it this way?
Well, we could use ClassRegistry::init('Model') in each of our component methods that need to use the model. If you have 10 methods in your component and only 1 of them uses the model this might work. However, what if you have 10 methods in your component and all 10 of them use the model? Well, you'd be calling ClassRegistry::init('Model') 10 times! That's a lot of overhead when what you really want is just 1 model object. With this method the component is creating one model object. The one we create in startup.
I hope this clarifies your questions and provides some insight into why I use this method for models in components.
Edit: Added a code clarification after I did some experimenting.
I think writing a component is overkill in this case and it would be cleaner to put the getEvents method into the Event model.
We had an outsourced engineer work on a quick feature DELETING items listed in our database. He says that the code is difficult because the "controller" is missing. Is there a pre-loaded controller for every function like that in cake, or is it weird that he is expecting a controller to be there for a feature we didn't have yet.
There is a generic AppController, but that's more of an abstract class in practice (you generally derive your other controllers from that).
It's not that weird at all that he's expecting a controller -- after all, you won't be able to call methods in the models (which is how I'm guessing you're doing delete) unless you have a point of control to call them from. In this case, the point of control is the controller.
So you can just create a controller. Here's a template to start from:
class SomeController extends AppController {
function delete() {
$this->Some->delete();
}
}
Then access /somes/delete (remember, URLs are generally /controller/action).
Now, he could be talking about the Cake Bake CLI app. That will take your DB tables, and walk you through an initial basic setup for your app. Generally it creates a basic skeleton for CRUD actions.
Either way, you need to create a controller (manually, or via Bake).
When you use the Cake bake function, it'll create all the controllers for you. When you don't use it, you'll need to create them manually. It makes no sense to make all the controllers at the begin, just make them when you really gonna write them would be good.
If you do not have a controller in CakePHP when you visit a page (http://www.youraddress.com/Newfeature) you receive a missing controller error:
Error: NewfeatureController could not be found.
Error: Create the class NewfeatureController below in file: app\controllers\newfeature_controller.php
You cannot get or delete data from the database without controllers - Understanding Model-View-Controller. You do not need the controller only for static pages in CakePHP.
I'm new to PHP and decided to use the cakePHP framework to help me get started.
I can't figure out one thing though, I want to call methods on the RequestHandlerComponent class to update a users last used IP address and other information, I figured the best place to put this would be in the beforeSave() method on the User model.
I can't figure out how to call the getClientIP method though.
The normal code that would otherwise go in the controller doesn't work. Is there another way to call this class if you're in the model and not the controller?
Class Level:
var $components = array('RequestHandler');
And in the function:
$this->data['User']['lastActiveIP'] = $this->RequestHandler->getClientIP();
Gives:
Undefined property: User::$RequestHandler
Call to a member function getClientIP() on a non-object
Components, by design, aren't available to models (without bypassing MVC convention - which you can do, of course). If you chose to force it to be available, look into ClassRegistry::init(). A better solution, I think, would be to employ the RequestHandler component in your controller (where it's meant to be used), set the lastActiveIp value in the controller (exactly as you've shown in your own example code) and pass the entire data array along to the model.
Now your component is being used where it should be and the model gets to remain ignorant about where it gets its data. At the risk of oversimplification, all the model should know is what to do with the data once it arrives; let the controller worry about collecting and packaging the data.
In addition to Rob's answer, maybe it's enough to put a bit of code together yourself that uses the general env('REMOTE_ADDR') or similar variables. Look at the RequestHandler code, it's not doing anything terrifically complicated.
You may even be able to call the component statically, which is slightly better than instantiating it in the model (still in violation of MVC though). Untested, but should work:
App::import('Component', 'RequestHandler');
RequestHandlerComponent::getClientIp();