web-dev-qa-db-fra.com

Meteor: Access Template Helper (ou variable) à partir d'un autre assistant

Comment référencer un assistant modèle à partir d'un autre? Par exemple...

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';
    }
});

J'ai aussi essayé Template.instance () .__ helpers.reusableHelper - tous sans succès.

Sinon, existe-t-il un moyen de définir des variables d’instance de modèle réactives?

XXX est un sous-modèle qui s'affiche plusieurs fois sur la même page.

22
Habib

Cela ressemble à utiliser du code commun, vous pouvez créer une autre fonction javascript contenant votre code réutilisable et l’appeler de partout où vous le souhaitez.

Comme dans votre code

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

et dans votre modèle d'aide

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';
    }
});

et 

Il existe également un moyen de définir une instance de modèle réactive des variables?

vous pouvez utiliser Variables de session ou Variable réactive

11
ajduke

Avertissement: Cela ne répond peut-être pas directement à votre question, mais il peut également être utile aux personnes confrontées à un cas d'utilisation similaire:

Parfois, il est facile de s’enfermer dans la "Meteor way", les règles Javascript standard sont oubliées.

Deux cas d’utilisation ressemblant à ce que vous essayez de faire:

1. Pour les assistants/événements auxquels vous pouvez accéder n'importe où du côté client, définissez simplement un assistant global.

Mettez ceci dans, disons, client/helpers.js:

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

Maintenant, Helpers.someFunction () est disponible pour tous modèles.

Si vous souhaitez lier l’instance de modèle locale à celle-ci pour une raison quelconque, il s’agit là encore de JS standard:

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

2. Pour créer des aides Blaze réutilisables à l'intérieur de modèles, utilisez Template.registerHelper

Par exemple, cette fonction utilise la bibliothèque "numeral" pour formater des nombres:

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

Vous pouvez utiliser ceci dans any template comme ceci:

{{numeral someNumberVariable format='0,0'}}
5
Lee Benson

J'ai trouvé une meilleure solution avec les crochets de collection:

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

Je deviens alors des fonctions de this, utilisables à la fois dans les aides et les modèles.

3
Almaju

j'avais quelque chose de similaire - j'avais 2 aides dans le même modèle qui avaient besoin d'accéder à la même fonction. Cependant, cette fonction 1) devait avoir accès à un var réactif dans le modèle, et 2) était une fonction de filtrage; je ne pouvais donc pas simplement transmettre les données de ce var réactif.

j'ai fini par définir la fonction de filtre dans les modèles onCreated () et je l'ai stockée dans une variable réactive, afin que les assistants puissent y accéder.

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);
    },

});
2
zim

cela vient juste de revenir au travail, et cette fois nous avons utilisé des modules. Dans ce cas, nous avions un certain nombre de fonctions importantes et liées qui devaient gérer les données d’un appel à l’autre. Je les voulais en dehors du fichier modèle mais sans polluer totalement la portée de Meteor. Nous avons donc créé un module (polluant la portée de Meteor 1x) et appelé ses fonctions à partir du modèle.

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());
    }
});

la sortie de la console est 7, 8.

0
zim

Ajoutant à la réponse de Nils, j'ai pu accéder aux aides de niveau Modèle dans les événements en utilisant le code suivant:

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

Cette réponse étant actuellement manquante, je voulais ajouter une mise à jour.

Dans la version actuelle de météore, vous devriez pouvoir appeler:

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

Vous devriez l'appeler comme ceci si vous voulez vous assurer que l'assistant a accès à this:

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

Mais soyez prudent - cela pourrait casser dans les futures versions de Meteor.

0
Nils Ziehn