2015-01-29 3 views
22

Как я могу ссылаться на помощник шаблона из другого? Например ...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 - это подшаблон, который отображает несколько раз на одной странице.

ответ

11

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

Как и в вашем code-

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

и в вас шаблон helper-

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

и

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

вы можете использовать Session variables или Reactive variable

+0

Я думаю, что управление большой ряд переменных сессии не будет быть слишком мудрым - возможно, местная коллекция будет лучше. С учетом сказанного, я думаю, что ваш ответ - отличный вариант. Должен был подумать об этом :) – Habib

13

Вы можете, но только с global template helpers.

Blaze._globalHelpers.nameOfHelper()

Вот пример вызова Iron:Router's 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) 
    } 
    } 
}); 

EDIT: К вашему второму вопросу. Вы можете вызывать один и тот же шаблон столько раз, сколько хотите на странице, и передавать в него разные атрибуты данных и/или использовать #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> 
+0

Я думаю, что вы правы ... Я могу передать 'reusableHelper' в качестве аргумента для подтемы ... Другими словами' {{each ...}} {{> XXX процент = reusableHelper}} {{/ each}} '- и в ссылке под шаблоном параметр. Спасибо – Habib

+0

Спасибо за этот ответ! – dalgard

5

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

Иногда легко попасть в «Метеорский путь», что стандартные правила 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

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

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'}} 
+0

UI.registerHelper теперь Template.registerHelper – mwarren

+0

Подход создания 'Helpers = {...}' не работал для меня, но 'Template.registerHelper (nameStr, function)' работал нормально. – Thor

0

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

В текущей версии метеора, вы должны быть в состоянии назвать :

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 */); 

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

0

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

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

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

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, которые можно использовать как в качестве помощников, так и в шаблонах.

2

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

В итоге я определил функцию фильтра в шаблонах 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); 
    }, 

}); 
0

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

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

выход консоли 7, 8.

Смежные вопросы