2015-01-29 24 views
22

Come posso fare riferimento a un helper di template da un altro? Per esempio ...Meteor: Access Template Helper (o variabile) da un altro helper

Template.XXX.helpers({ 
    reusableHelper: function() { 
     return this.field1 * 25/100; //or some other result 
    }, 
    anotherHelper: function() { 
     if (this.reusableHelper() > 300) //this does not work 
      return this.reusableHelper() + ' is greater than 300'; 
     else 
      return this.reusableHelper() + ' is smaller than 300'; 
    } 
}); 

Ho anche provato Template.instance() .__ helpers.reusableHelper - il tutto senza fortuna.

In alternativa esiste un modo per definire variabili di istanza Template reattive?

XXX è un modello secondario che esegue il rendering più volte nella stessa pagina.

risposta

11

Questo simile uso del codice comune, è possibile effettuare un'altra funzione javascript che contiene il codice riutilizzabile e chiamarlo da qualsiasi luogo richiesto.

Come nella tua code-

function calcField(field){ 
    return field * 25/100 
} 

e in voi modello Aiutante-

Template.XXX.helpers({ 
    reusableHelper: function() { 
     return calcField(this.field1); 
    }, 
    anotherHelper: function() { 
     if (calcField(this.field1) > 300) 
      return calcField(this.field1) + ' is greater than 300'; 
     else 
      return calcField(this.field1) + ' is smaller than 300'; 
    } 
}); 

e

In alternativa c'è un modo per definire istanze Template reattiva variabili?

è possibile utilizzare Session variables o Reactive variable

+0

Penso che la gestione di quel grande una serie di variabili di sessione non avrebbe essere troppo saggio - forse una collezione locale sarebbe meglio. Detto questo, penso che la tua risposta sia un'ottima opzione. Avrei dovuto pensarci :) – Habib

13

È possibile, ma solo con global template helpers.

Blaze._globalHelpers.nameOfHelper()

Ecco un esempio chiamando Iron:Router's pathFor di supporto globale.

Template.ionItem.helpers({ 
    url: function() { 
    var hash = {}; 
    hash.route = path; 
    hash.query = this.query; 
    hash.hash = this.hash; 
    hash.data = this.data; 
    var options = new Spacebars.kw(hash); 

    if (this.url){ 
     return Blaze._globalHelpers.urlFor(options) 
    } else if(this.path || this.route) { 
     return Blaze._globalHelpers.pathFor(options) 
    } 
    } 
}); 

EDIT: Per la tua seconda domanda. È possibile richiamare lo stesso modello tutte le volte che si desidera su una pagina e passare direttamente attributi di dati diversi all'interno di esso e/o utilizzare il wrapper del modello di blocco #each per iterare sui dati. #each chiamerà un modello molte volte dandogli un contesto di dati diverso ogni volta.

#each Esempio

<template name="listOfPosts"> 
    <ul> 
    {{#each posts}} 
     {{>postListItem}} <!--this template will get a different data context each time--> 
    {{/each}} 
    </ul> 
</template> 

Attributi Esempio

<template name="postDetails"> 
    {{>postHeader title="Hello World" headerType="main" data=someHelper}} 
    {{>postHeader title="I am a sub" headerType="sub" data=newHelper}} 
    {{>postBody doc=bodyHelper}} 
</template> 
+0

Penso che tu abbia ragione ... Potrei passare il 'reusableHelper' come argomento per il subtemplate ... In altre parole' {{each ...}} {{> XXX percentuale = reusableHelper}} {{/ each}} '- e nel sotto-modello si fa riferimento al parametro. Grazie – Habib

+0

Grazie per questa risposta! – dalgard

5

responsabilità: questo non può rispondere alla tua domanda direttamente, ma potrebbe essere utile per le persone bloccato con un uso simile case:

A volte è facile rimanere bloccati nella "modalità Meteor", le regole Javascript standard vengono dimenticate.

Due casi d'uso che suonano simili a quello che stai cercando di fare:

1.Per gli helper/eventi a cui è possibile accedere ovunque sul lato client, è sufficiente impostare un helper globale.

mettere questo, diciamo, client/helpers.js:

Helpers = { 
    someFunction: function(params) { 
     /* Do something here */ 
    } 
} 

Ora Helpers.someFunction() è disponibile per tutti i modelli.

Se si desidera associare l'istanza modello locale per qualche motivo, ancora una volta, di JS serie:

var boundFunction = Helpers.someFunction.bind(this); 

2. Per creare riutilizzabili aiutanti Blaze all'interno di modelli, utilizzare Template.registerHelper

ad esempio, questa funzione utilizza la libreria "numerale" per formattare i numeri:

Template.registerHelper('numeral', function(context, opt) { 
    var format = (opt.hash && opt.hash.format) || '0,0.00'; 
    return numeral(context || 0).format(format); 
}); 

È possibile utilizzare questo in qualsiasi modello in questo modo:

{{numeral someNumberVariable format='0,0'}} 
+0

UI.registerHelper è ora Template.registerHelper – mwarren

+0

L'approccio alla creazione di 'Helpers = {...}' non ha funzionato per me, ma 'Template.registerHelper (nameStr, function)' ha funzionato correttamente. – Thor

0

Dal momento che questa risposta è attualmente mancano - ho voluto aggiungere un aggiornamento

Nella versione di meteoriti corrente, si dovrebbe essere in grado di chiamare :

var TEMPLATE_NAME = //the name of your template... 
var HELPER_NAME = //the name of your helper... 
Template[TEMPLATE_NAME].__helpers[' '+HELPER_NAME] 

si dovrebbe chiamare in questo modo, se si vuole fare in modo l'assistente ha accesso a this:

var context = this; 
Template[TEMPLATE_NAME].__helpers[' '+HELPER_NAME].call(context,/* args */); 

Ma attenzione: questo potrebbe rompersi nelle future versioni di Meteor.

0

Aggiungendo alla risposta Nils', sono stato in grado di accedere aiutanti livello di modello a eventi utilizzando il seguente codice:

'click a#back': (event, instance) -> 
    if instance.view.template.__helpers[' complete']() && instance.view.template.__helpers[' changed']() 
     event.preventDefault() 
3

ho trovato una soluzione migliore con ganci di raccolta:

Item = new Mongo.Collection('Items'); 
Item.helpers({ 
    isAuthor: function(){ 
     return this.authorId == Meteor.userId(); 
    }, 
    color: function(){ 
     if(this.isAuthor()) 
      return 'green'; 
     else 
      return 'red'; 
    } 
}); 

I diventa quindi funzioni di this, utilizzabile in entrambi gli helper e modelli.

2

ho avuto qualcosa di simile - ho avuto 2 aiutanti nello stesso modello che aveva bisogno di accedere alla stessa funzione. tuttavia, quella funzione 1) aveva bisogno di accedere a una var reattiva nel modello, e 2) è una funzione di filtro, quindi non potevo semplicemente passare i dati di quella var reattiva.

Ho finito per definire la funzione filtro nei modelli onCreated() e l'ho memorizzato in una variabile reattiva, così gli helper potevano accedervi.

Template.Foo.onCreated(function() { 

    this.fooData = new ReactiveVar(); 

    function filterFoo(key) { 
     var foo = Template.instance().fooData.get(); 
     // filter result is based on the key and the foo data 
     return [true|false]; 
    } 

    this.filterFoo = new ReactiveVar(filterFoo); 

}); 

Template.Foo.helpers({ 
    helper1: function() { 
     var filterFn = Template.instance().filterFoo.get(); 
     return CollectionA.getKeys().filter(filterFn); 
    }, 
    helper2: function() { 
     var filterFn = Template.instance().filterFoo.get(); 
     return CollectionB.getKeys().filter(filterFn); 
    }, 

}); 
0

questo appena tornato al lavoro, e questa volta abbiamo usato i moduli. in questo caso, abbiamo avuto un numero di grandi funzioni correlate che dovevano mantenere i dati attraverso le chiamate. Li volevo al di fuori del file di modello, ma non inquinando completamente l'ambito Meteor. quindi abbiamo creato un modulo (inquinando lo scope Meteor 1x) e chiamato le funzioni in esso contenute nel modello.

lib/FooHelpers.js:

FooHelpers = (function() { 
    var _foo; 

    function setupFoo(value) { 
     _foo = value; 
    } 

    function getFoo() { 
     return _foo; 
    } 

    function incFoo() { 
     _foo++; 
    } 

    return { 
     setupFoo: setupFoo, 
     getFoo: getFoo, 
     incFoo: incFoo 
    } 
})(); 

FooTemplate.js:

Template.FooTemplate.helpers({ 
    testFoo: function() { 
     FooHelpers.setupFoo(7); 
     console.log(FooHelpers.getFoo()); 
     FooHelpers.incFoo(); 
     console.log(FooHelpers.getFoo()); 
    } 
}); 

uscita della console è di 7, 8.

Problemi correlati