2014-06-14 11 views
10

C'è un modo per estendere l'opzione data quando si utilizza IronRouter e il RouteController, Sembra che viene ignorato quando ho ereditato da un controllore super, il controller bambino non si estende il definito data proprietà. Ho avuto problemi la classica con l'opzione yieldTemplates su un percorso e utilizzato una soluzione alternativa (sottolineatura _extends), ma non ha funzionato in questo caso:IronRouter sul controller percorso

ApplicationController = RouteController.extend({ 
    data: function(){ 
      return { 
       user: Meteor.user() 
     }  
    } 
}); 

ChildController = ApplicationController.extend({ 
    data: function(){ 
     return { 
       // I expect to inherit Meteor.User ????? 
       someData: {} 
     } 
    } 
}); 

EDIT:

Dopo aver utilizzato underscore e la funzione extend di ereditare il prototipo di funzione, sono ancora in grado di ereditare in di route definizione che usa la ChildController

this.route('someRoute', { 
    template: 'task_template', 
    //tasks is not available on the template 
    data: function() { 
      var base = ChildController.data.call(this); 
      console.log(base); 
      return _.extend(base, { 
       tasks: Tasks.find({state: 'Open'}) 
      }); 
}); 
+0

Puoi spiegare perché vuoi fare questo e quello che stai cercando di realizzare? Forse c'è un altro modo? –

+0

È necessario anche richiamare il controllore (super) genitore dai dati di child(). – LSerni

risposta

8

io uso qualcosa di simile a questo in un'applicazione di produzione:

Router.route('/test/:testparam', { 
    name: 'test', 
    controller: 'ChildController' 
}); 

ParentController = RouteController.extend({ 
    data: function() { 
     console.log('child params: ', this.params); 
     return { 
      foo: 'bar' 
     }; 
    } 
}); 

ChildController = ParentController.extend({ 
    data: function() { 
     var data = ChildController.__super__.data.call(this); 
     console.log(data); 
     return data; 
    } 
}); 

Utilizzando __super__ sembra fare il trucco!
È possibile che usare _.extend per estendere i dati (http://underscorejs.org/#extend)

+0

Questo può essere fatto senza estendere il controller? utilizzando direttamente la definizione '' this thisroute '? – Kostanos

1

Penso _.extends dovrebbe funzionare in questo caso:

ChildController = ApplicationController.extend({ 
    data: function() { 
    var base = ApplicationController.data.call(this); 
    return _.extends(base, { 
     someData: {}, 
    }); 
    } 
}); 
+0

È 'extends' o' extend', ho provato entrambi ma non sono ancora riuscito a utilizzare i dati da 'ChildController'. Se rimuovo la definizione 'data' da' ApplicationController' funziona – Warz

+1

Questo non ha funzionato, nessun'altra idea. Hai ancora questo problema – Warz

3

da aggiungere alla risposta selezionata, si noti che se si sta utilizzando la seguente CoffeeScript produrrà lo stesso risultato:

class @ChildController extends ParentController 
    data: -> super() 
    # or if you want to add to it: 
    data: -> 
    _.extend super(), { extraThing: 'some value' } 
+2

Davvero non so perché la gente non ha votato 4 u. Solo una soluzione eccezionale. Molte grazie! – haotang

0

Un'altra opzione che può ottenere lo stesso risultato è definire un metodo sul controller principale, quindi chiamarlo usando super senza estendere nulla. È un po 'più di lavoro per ogni controller ma è più facile da applicare retroattivamente. Inoltre rende il metodo opzionale per il controller figlio piuttosto che per impostazione predefinita.

ApplicationController = RouteController.extend({ 
     waitOn: function() { 
      return [Meteor.subscribe('customUserPublish')]; 
     }, 
     GetProfileWithEmail: function(){ 
      var user = Meteor.user(); 
      var profile = user.profile; 
      profile.email = user.emails[0].address; 
      return profile; 
     } 
    }); 

ProfileController = ApplicationController.extend({ 
     waitOn: function() { 
      return [Meteor.subscribe('anotherCollectionPublish')]; 
     }, 
     data: function(){ 
      return { 
      profile: function(){ 
       var profile = ApplicationController.__super__.GetProfileWithEmail.call(this); 
       console.log('profile from super', profile); 
       return profile; 
      } 
      } 
     } 
}); 

Ricordate che è necessario iscriversi alla raccolta pubblicata come bene e credo che è necessario utilizzare l'opzione di matrice waitOn in modo che possa unire i subs correttamente (per ammissione io uso sempre formato di array in modo YMMV) . Puoi accedere ai dati nel tuo modello utilizzando {{#with profile}} ... {{/ with}} o se stai tornando indietro un array di oggetti usa {{#each profile}} ... {{/ each }}.

Problemi correlati