0

My Ember.js app is set up roughly like this:

Router:

App.Router.map ->
  @resource('site', { path: '/' }, ->
    @resource('dashboard')
    @resource('account')
    @resource('pages', { path: '/:page_slug'}))

Routes:

App.ApplicationRoute = Ember.Route.extend
    model: ->
        return App.Site.find(1)

App.PagesRoute = Ember.Route.extend
    model: (params)->
        return App.Page.find(params.page_slug)

EDIT:

Controller (JS not Coffee):

App.PagesController = Ember.ObjectController.extend({
    needs: 'ApplicationController',
    ...
});

I have an ApplicationController and a PagesController. When I'm on a page, I want to call an action to delete the current page. If I place it in the PagesController it works kind of ok, but a navigation menu with a list of pages in the ApplicationView doesn't get updated until I refresh the page. So... I assume I need to place the action in the ApplicationController and add needs: ['ApplicationController'] to my PagesController.

However, when I do that, everything in my Pages template disappears.

I have an {{outlet}} in my Application template and another on in the Site template which ultimately displays the Pages template. Yeah, complicated, I know and there's probably a better way to do it, so any suggestions would be greatly appreciated. Oh and BTW, I'm a real Ember.js newb, so examples need to be spelled out explicitly. (Drawing them with pretty colors in crayon would actually be ideal.)

Thanks in advance for any help.

Here's the refresh issue. In the root resource site I'm loading in one Site model which the Rails backend returns using the url being sent in. Eventually, this app will be used with multiple domains, and each domain will be served it's own website (roughly based on the WP-Multisite concept). Then in the pages route, I'm loading one page of the site based on its slug attribute. That's all working fine. So, now I want to allow the user to be able to add and remove pages as they want.

So, the issue is this. When I delete a page at the PagesController level, the page deletes just fine, but the ApplicationController doesn't get notified. Namely, my nav menu:

<ul class="left">
  {{#each page in page}}
    <li>{{#link-to 'pages' page.slug}}{{page.menu_name}}{{/link-to}}</li>
  {{/each}}
    <li id="add-page-button"><a data-tooltip title="Click here to add a new page to your site." href="#" data-reveal-id="addPageModal" data-reveal>+</a></li>
</ul>

doesn't get notified that a page is missing and so it doesn't update the nav menu by removing that page from the list. Adding works fine, the nav list is updated when a new page is added, but I'm doing that at the ApplicationController level like so:

addNewPage: ->
            # Get the site
            site = @get('model')
            # Get all the pages associated with the site
            pages = site.get('page')

            title = this.get('newTitle')
            if (!title.trim())
                return

            slug = this.get('newSlug')
            if (!slug.trim())
                return

            menu_name = this.get('newMenuName')
            if (!menu_name.trim())
                return

            # Create a new page passing in our title, slug and menu_name
            pages.create({title: title, slug: slug, menu_name: menu_name})
            # Save the pages
            pages.save()

            if (pages.isError)
                console.log(pages.errors)
            else
                @set('newTitle', '')
                @set('newSlug', '')
                @set('newMenuName', '')
                $('#addPageModal').foundation('reveal', 'close')

And this is my deletePage code on the PagesController (sorry, I've got a mix of JS and CoffeeScript):

deletePage: function (slug) {           
    var page = this.get('model');
    this.get('ApplicationController').deletePage(page);
    this.toggleProperty('isEditingTitle');
    this.toggleProperty('isShowingDeleteConfirmation');
    this.transitionToRoute('site.index');
}

When I try this, Ember rather helpfully lets me know I need to add needs but again, when I do that, my Pages template is blank.

Oh yes, I have even tried setting the target attribute on the button calling the deletePage action.

I realize what I need to do is somehow access the Site model in my PagesController, but how should I go about that.

This post has taken on epic proportions. Sorry about that. Thanks again for any help.

reblevins
  • 99
  • 1
  • 8

2 Answers2

0

needs doesn't do anything on the route, if you want to access a controller from a route you can just use this.controllerFor('application')

Additionally when using needs in a controller definition it should be like this needs: 'application' or needs: ['foo', 'application']...

Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
  • Right, I had tried that in the route since it wasn't working for me in the controller, but I must have forgotten to remove it before posting here. And `needs: 'application'` doesn't work for me either, I'm afraid. I'll edit my original post. – reblevins Mar 09 '14 at 17:56
0

Okay, all, I figured it out. For posterity's sake (and others who go looking for this). Here's how to delete an object in a model that has a belongsTo association.

ApplicationController:

deletePage: function () {
  # First we find the Site which all pages belongTo
  # Just ignore the hard-coded '1' it's something I have to do to get it to work
  site = App.Site.find(1);

  # Then we get the current model, i.e., the 'page' we're on and about to delete
  page = this.get('model');

  # Then, we get all 'pages'
  pages = site.get('page');

  # We remove the object from the page which updates the navigation menu
  pages.removeObject(page);

  # We delete the record and save the 'pages' model
  page.deleteRecord();
  pages.save();
}

Pages template:

{{#if isShowingDeleteConfirmation}}
<div class="large-7 large-offset-5">
  <label class="inline left">Are you sure? (Can't be undone)</label>
  <button {{action 'deletePage'}} class='button tiny alert'>Yes</button>
  <button {{action 'cancelDeletePage'}} class='button tiny'>Cancel</button>
</div>
{{else}}
<div class="large-2 right">
  <button {{action 'showDeleteConfirmation'}} class='button tiny alert'>Delete Page</button>
</div>
{{/if}}

I can show you the attributes and logic behind the if...else statement if you need me to.

Basically, the user clicks on the 'Delete' button, showing the other buttons 'yes' and 'cancel'. Once 'yes' is clicked, the deletePage action gets called.

I found very little documentation on the deleteRecord method and basically had to piece this all together myself. Perhaps there's a better way and this can be refactored. Just let me know in the comments.

reblevins
  • 99
  • 1
  • 8