Подтвердить что ты не робот

Meteor: Access Template 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';
    }
});

Я также попробовал Template.instance().__ helpers.reusableHelper - все без везения.

Альтернативно существует ли способ определить реактивные переменные экземпляра шаблона?

XXX - это подшаблон, который отображает несколько раз на одной странице.

4b9b3361

Ответ 1

Это, как и использование общего кода, вы можете сделать еще одну функцию javascript, которая содержит ваш многоразовый код и вызвать его там, где вам нужно.

Как в вашем коде -

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

и в вашем помощнике шаблонов -

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

и

В качестве альтернативы существует способ определения реактивного экземпляра шаблона переменные?

вы можете использовать переменные сеанса или реактивную переменную

Ответ 2

Вы можете только с глобальными помощниками шаблонов.

Blaze._globalHelpers.nameOfHelper()

Вот пример, вызывающий глобальный помощник Iron: Router pathFor.

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

РЕДАКТИРОВАТЬ: К вашему второму вопросу. Вы можете вызывать один и тот же шаблон столько раз, сколько хотите на странице, и передавать в него различные атрибуты данных и/или использовать обертку шаблона блока #each для перебора данных. #each будет вызывать шаблон много раз, давая ему другой контекст данных каждый раз.

#each Пример

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

Пример атрибутов

<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>

Ответ 3

Отказ от ответственности: это может не отвечать на ваш вопрос напрямую, но это может быть полезно для людей, придерживающихся аналогичного варианта использования:

Иногда легко попасть в "путь Метеор", что стандартные правила Javascript забываются.

Два варианта использования, которые похожи на то, что вы пытаетесь сделать:

1. Для помощников/событий, к которым вы можете получить доступ в любом месте на стороне клиента, просто установите глобальный помощник.

Поместите это, скажем, client/helpers.js:

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

Теперь Helpers.someFunction() доступен для всех шаблонов.

Если вы хотите связать экземпляр локального шаблона с ним по какой-либо причине, опять же, это стандартный JS:

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

2. Чтобы создать многоразовые помощники Blaze внутри шаблонов, используйте Template.registerHelper

Например, эта функция использует библиотеку "numeral" для форматирования чисел:

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

Вы можете использовать это в любом шаблоне следующим образом:

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

Ответ 4

Я нашел лучшее решение с коллекционными крючками:

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

Затем я становлюсь функциями this, которые можно использовать как в помощниках, так и в шаблонах.

Ответ 5

У меня было что-то похожее - у меня было 2 помощника в одном шаблоне, которым нужен доступ к одной и той же функции. однако, эта функция 1) нуждается в доступе к реактивному var в шаблоне, а 2) является функцией фильтра, поэтому я не мог просто передать данные этого реактивного var.

i в конечном итоге определил функцию фильтра в шаблонах onCreated() и сохранил ее в реактивной переменной var, чтобы помощники могли получить к ней доступ.

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

});

Ответ 6

Поскольку этот ответ в настоящее время отсутствует - я хотел добавить обновление

В текущей версии метеора вы можете позвонить:

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

Вы должны вызвать его так, если хотите, чтобы хелпер имел доступ к this:

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

Но будьте осторожны - это может сломаться в будущих версиях Метеор.

Ответ 7

Добавив ответ Nils, я смог получить доступ к помощникам уровня шаблона в событиях, используя следующий код:

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

Ответ 8

это снова появилось на работе, и на этот раз мы использовали модули. в этом случае у нас было несколько крупных связанных функций, которые должны были поддерживать данные через вызовы. Я хотел, чтобы они были вне файла шаблона, но не полностью загрязняли область Метеор. поэтому мы создали модуль (загрязняющий область Метеор 1x) и назвали функции в нем шаблоном.

Библиотека/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());
    }
});

консольный вывод - 7, 8.