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 - это подшаблон, который отображает несколько раз на одной странице.
Ответы
Ответ 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.