Pass a property of the model to the template in ItemView - marionette

I want to pass a property of my model to the template, so I presume I need a serializeData function, I tried this
serializeData:function(){
return this.model.toJSON().extend({_schema:this.model.schema});
}
but it complained about not being able to extend the output of toJSON. This must be a standard trick, stick some value from the prototype into the serialised form so the template can get it's hands on it.

Use templateHelpers for this use case – serializeData works better for replacing the model attributes entirely, or scoping them down.
templateHelpers: function()
{
return { _schema: this.model.schema };
}

Harladson's answers is the best, but in case someone else comes looking different approach you can do this:
serializeData:function(){
var data = this.model.toJSON();
data._schema = this.model.schema;
return data;
}

Related

Creating models with many variables

Can anyone help me interpret this code?
What does $gallery = false mean? Why mention it instead of just erasing it?
models/post_model.php
public function post($post_parent_ID, $gallery = false)
{
}
If you want to pass any default value for any argument, you need to write it like this.
Then why it's false - Because by default, you don't like to use it. But you have kept an option for future use. Now when you pass second argument with any other value, it will work. Otherwise, your function will work by using first argument.
Function parameters can sometimes be optional, which means they don't need to contain any data.
public function post($post_parent_ID, $gallery = false)
{
}
Means that when I'd send something to this function I can do:
$this->post(1);
or
$this->post(1, 2);
Inside the post function you would check wether $gallery is filled or not depending on the use needed.

Laravel 5 How to follow DRY in my simple controller logic?

I have some simple logic in my Controller. But I often use it in other method. Here is an example.
In my controller.
public function method1()
{
if(isset(Auth::user()->showroom->name)){
$showroomName = Auth::user()->showroom->name;
}else{
$showroomName = "Belum Ada Izin";
}
return view('method1view', compact('showroomName'));
}
public function method2()
{
if(isset(Auth::user()->showroom->name)){
$showroomName = Auth::user()->showroom->name;
}else{
$showroomName = "Belum Ada Izin";
}
return view('method2view', compact('showroomName'));
}
... so on
How I can follow DRY principle in my case?
Any help will be appreciated.
Thanks in advance.
For cleaner and shorter syntax, use data_get helper:
data_get(Auth::user(), 'showroom.name', 'your default value');
This in most cases comes handy, but not always is the best way.
However, in your example it seems, that maybe in fact you'd like to simply share this variable across your views - use share or a View Composer described in the docs.
In your Showroom model you could include the following function:
public function getNameAttribute($value)
{
return isset($value) ? $value : 'Belum Ada Izin';
}
That's assuming you want that behavior everywhere showroom->name is used. If not, make the function getNameWithDefaultAttribute, check $this->name in the body, and reference it in the controller like Auth::user()->showroom->name_with_default

How to enforce Grails command objects have been validated?

We use the following general pattern with Grails controllers and command objects
SomeController {
def someAction() {
SomeCommandObject co = SomeCommandObject.valueOf(params)
if(!co.validate()) {
// return bad request
}
someService.doWork(co)
// return ok
}
SomeService {
def doWork(SomeCommandObject co) {
notTrue(!co.hasErrors(), 'cant have errors') // Commons validation
// do actual work
}
}
Apparently, if co.validate() has not been called, .hasErrors() will always return false. Is there a better way to enforce that .validate() has been called before a command object is passed between application layers? We don't want to pass around invalid command objects but we don't want to force every new method to re-validate the command object either.
Note: We aren't using the default controller/command object creation pattern because we need to do some custom parameter map checking, we use a static valueOf method instead to create the command object. Answers that change that practice are also welcome.
EDIT: A little more info on why we aren't using the 'default' controller/command object creation. Specifically why we aren't doing ..
def someAction(SomeCommandObject co) {
}
We have a requirement to disallow random query parameters, eg. endpoint/object?color=blue. To do that we need access to the parameter map in the command object to verify that it doesn't contain any 'unexpected' parameter keys. As I understand it, the default way would just create a member on the CO named color, and I don't see how to prevent arbitrary members using even custom validators. I'd happily entertain suggestions for doing so, thereby allowing us to use this default means.
Yes; what you can do is pass the command object as a parameter to the controller, and then the command will always be validated automatically.
Also, what you can do, is to make a filter or similar, so that you don't have to check for the hasErrors() each time, but handle all the cases in the same way (for example, by throwing an error, or returning with a specific response).
In an application we created, we had something like:
withValidCommand(cmd) {
// do work
}
Which worked pretty well. But maybe you can come up something even more elegant.
You should be doing this:
def someAction(SomeCommandObject co) {
if (!co.hasErrors()) {
someService.doWork(co)
}
}
By passing SomeCommandObject in as the argument grails will automatically populate it from params and validate. No need to do it manually.

MVC best practice for create/confirm/persist process

I have an addAction like this:
public function addAction(Request $request)
{
$object = new Object();
$object->setAttrib('foo');
if($object->isValid())
{
$session->set('_object', $object);
return $this->redirect('confirmAction');
}
}
and in the confirmAction:
public function confirmAction($confirm = 'not_confirmed')
{
if($confirm == 'confirm')
{
$object = $session->get('_object');
if($object->isValid())
{
$entityManager->persist($object);
$session->remove('_object');
return $this->redirect('listAction');
}
}
$this->renderTemplate('with confirm link');
}
I dont like the $session->set part. What is the best practice for this create/confirm/persist things?
Well, you should ask yourself whether or not you want to use JavaScript. A confirmation box would be in my opinion the most sensible solution, since the client doesn't make another round-trip to the server.
If for some reason you don't want to use JavaScript, your method is the way to go. Instead of using $session->set('...');, you could use $session->setFlash('...'), which will store the value in the session for only one request and deletes it afterward.
If a user decides not to confirm the action, you could use $session->setFlash('...') yet again to display the previous state of a form. Using this method is better, because you won't be having any leftover session values just hanging there.

Backbone.js Inherit Views

I have a FormView which handles such events as save and cancel. I also have an AjaxFormView that handles save, cancel and get form by ajax. I have an AssetFormView that handles save, cancel, get by ajax, delete, and print.
So on and so forth. there is considerable repitition.
I found a post this post http://kalimotxocoding.blogspot.com/2011/03/playing-with-backbonejs-views.html
where he shows you can extend views. However, I'm finding that when i have multiple versions of views on the page there are properties cross pollinating. Is there no built in way to inherit views in backbone, that is safe?
Thanks,
Raif
* hmmm well, this stuff is pretty thick and my current cross pollination issue may be ( probably is ) the result of some error on my part, but the question still stands, is there not and would it not be an important feature to have, some way to inherit views?
I'd like to see what you mean when you say that your properties are cross-pollenating.
The View.extend mechanism works quite well. Do be aware, though, that you are extending one prototype with new functions. With prototypical inheritance, the prototype shares it's objects with the new instances.
I am guessing that when you say that your properties are "cross-pollenating", you are actually doing something like this:
var baseModel = Backbone.Model.extend({
defaults: {
foo: { bar: "baz" }
}
});
Since the objects are shared, every instance of baseModel ends up having the same object for foo, giving the feeling of cross-pollination.
If instead, you define your defaults as a function, then each instance will get it's own copy of the foo object and your cross-pollination goes away.
var baseModel = Backbone.Model.extend({
defaults: function() { return {
foo: { bar: "baz" }
} }
});
Of course, without code, we can't be certain to what your problem is. Just know that this mechanism has been well-used among the community without trouble. It is safe. You just need to understand what is going on.
I'm not sure if this is the same problem you're having but I wanted to have some events defined in the parent class and then have the child class extend the property without overriding it.
If I did it like this, I was overriding what the parent defined:
App.parent = Backbone.View.extend({
events: {
'click #button-add': 'onAddButtonClicked'
'click #button-delete': 'onDeleteButtonClicked'
}
onAddButtonClicked: function() {
console.log('onAddButtonClicked');
},
onDeleteButtonClicked: function() {
console.log('onDeleteButtonClicked');
}
});
App.child = App.parent.extend({
initialize: function() {
// This looks redundant but it seems to protect App.parent::events
this.events = _.extend({}, this.additionalEvents, this.events);
// THIS IS WRONG and results in errors when I have multiple childdren:
_.extend(this.events, this.additionalEvents); // <-- this seems to change the parent
}
additionalEvents: {
'click #button-additional': 'onOtherButtonClicked'
},
onOtherButtonClicked: function() {
console.log('child:onOtherButtonClicked');
}
});
When extending the parent's events like this:
_.extend(this.events, this.additionalEvents);
I'd get "Uncaught Error: Method 'onOtherButtonClicked' does not exist" because I was modifying App.parent's events field. App.child2 was blowing up because it couldn't see the events that were put there by App.child.
By changing it to:
this.events = _.extend({}, this.additionalEvents, this.events);
I was able to protect the parent.

Resources