Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Collection Reactive Join #147

Closed
pctj101 opened this issue May 19, 2012 · 10 comments
Closed

Multiple Collection Reactive Join #147

pctj101 opened this issue May 19, 2012 · 10 comments

Comments

@pctj101
Copy link

pctj101 commented May 19, 2012

Say I have a few collections:
Chefs
Customers
Dishes

And for each day in my schedule, I need to remember which Chef, is cooking which Dish, for which Customer.

I want to display it like a battleship grid...

Day XYZ

Chef #1
Grid
X axis - Customer
Y axis - Dish

Chef #2
Grid
X axis - Customer
Y axis - Dish

I'm going to use a few templates like:

Template: home
{{#each chefs}}
{{>chef}}
{{/each}}

Template: chef
{{#each customers}}
{{> customer}}
{{/each}}

Template: customer
{{#each dishes}}
{{> dish}}
{{/each}}

Template: dish

<template name='dish'>
  <div class='servethis {{serving}}'>Serve {{name}}</div>
</template>

Well.. by the time I click .servethis, that template has no idea what 'customer' or 'chef' it exists under.

We can pass the chef._id and customer.id into the template using a helper and modifying the dish to include:
dishes = _.map(dishes, function(dish) { return {dish: dish, customer_id = customer.id, chef_id = chef.id}; } );

But now dishes is an Array, not a reactive Collection.... which presents a problem when Customers.find() returns 0 results at first, then 10 results later for example. So it seems modifying the return value of find() is not a good idea when directly used as a template helper.

Alternatively we can cure this by using a single Collection called ChefsCustomerDishes. However to loop this, we'd need to pre-create all the objects for every possible combination of at least Chef + Customer, leaving only the Dish attribute unknown. Otherwise, without pre-creating these objects, there would be nothing for mustache to loop through.

This is particularly problematic when you factor in dates... because precreating all these records for all dates just for the sake of display doesn't seem like the optimal approach.

I've considered using jQuery to suck out all the _id's from the DOM. For example:

<div class='date' data-date='2012-05-15'>
  <div class='chef' data-chefid='1232390582'>
    <div class='customer' data-customerid='23095fffabb'>
      <div class='dish' data-dishid='f00df00d'>
          <div class='servethis'>Click me</div>
      </div>
    </div>
  </div>
</div>

But then I realized that using jQuery to extract my function variables seemed a bit suboptimal.

   serveThis(
                    $(e.target).closest(".date").data("date")
                    $(e.target).closest(".chef").data("chefid")
                    $(e.target).closest(".customer").data("customerid")
                    $(e.target).closest(".dish").data("dishid")
    );

However, even with that solution it leaves the helpers abandoned.. for example

Template.dish.serving = function() {
    // this = dish object, but we don't know what HTML element it is on the dom because 
    //   the same dish object is reused multiple times under different chefs and customers
    day = $("?????"); // hmm!!! 
    chef = $("?????"); // hmm!!! 
    customer = $("?????"); // hmm!!! 

    // Are we serving this dish?
    if (serving) { 
        return "serving";
    } else {
        return "";
    }
}

Perhaps there's a better way?

@TaraRed
Copy link
Contributor

TaraRed commented May 19, 2012

The last thing is not true, since you have set data-dishid you can access it.

Other than that, I think it would be nice to be able to do something like {{#each chefs}}{{#each customer}}{{chefs.name}}{{/each}}{{/each}} as well as something similar when accessing it from Template.dish.serving, like this.ancestor('chefs').name.

@pctj101
Copy link
Author

pctj101 commented May 20, 2012

The problem is that I use the same dish._id in multiple places. So yes I can tell which dish, but not for which Customer or by which Chef, which is the main goal.

@TaraRed
Copy link
Contributor

TaraRed commented May 20, 2012

Uhm, you can...

                $(e.target).closest(".date").data("date")
                $(e.target).closest(".chef").data("chefid")
                $(e.target).closest(".customer").data("customerid")
                $(e.target).closest(".dish").data("dishid")

@pctj101
Copy link
Author

pctj101 commented May 20, 2012

@TomWij / Yes, you can do that when it is a reaction to a mouseclick. But it doesn't work when it's a helper for example to determine if a css classname is added to a

tag for example since {{serving}} isn't passed an event object.

<div class='servethis {{serving}}'>Serve {{name}}</div>

@dgreensp
Copy link
Contributor

In a template, the Handlebars ../ path prefix might help: http://handlebarsjs.com/#paths

In an event handler, there isn't a great way to do this at present. If you want to get the data for a node besides the event target, the function you want is findEventData in packages/liveui/liveui.js. It's a local, inaccessible function, but everything it uses is accessible.

@pctj101
Copy link
Author

pctj101 commented May 24, 2012

@dgreensp Thanks, that's an interesting approach. Let me see how far that gets me.

@n1mmy
Copy link
Contributor

n1mmy commented Jun 20, 2012

@pctj101 Did handlebars .. do what you want? Did you end up with a workable pattern? Should I close this bug?

@audreyfeldroy
Copy link
Contributor

I'm closing this for now, but @pctj101 if that doesn't work, comment here about what happened and I'll reopen this.

@spastai
Copy link

spastai commented Nov 19, 2012

Having template

{{#each requests}}
Confirm
{/each}}

Template.parentItem.events({
'click .confirm': function (event, template) {
    console.dir(template.data);
}
});

outputs parentItem properties

@Lepozepo
Copy link

Lepozepo commented Mar 9, 2013

Thank you spastai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants