Повторное использование шаблона blaze, как мне получить доступ к вспомогательным функциям других шаблонов?

Я пытаюсь настроить диалоговое предупреждение MDC. Вместо того, чтобы копировать и вставлять его в каждое представление, которое требует этого, я оборачиваю диалоговое окно в его собственный шаблон. Кажется, что шаблон работает, диалоговое окно открывается и работает как обычно, однако я не могу установить для него вспомогательную функцию, которая работает. Я попытался использовать вспомогательную функцию родительского шаблона и даже создать для нового шаблона собственный файл js. Ни одно из этих решений не захватывает данные правильно.

<template name="transactionAlert">
...
<div class="mdc-dialog__content" ><p>Are you sure you wish to continue with this transaction? It could cost up to: <b class="warning-value">${{maxCost}} USD</b></p>
...
</template>
<template name="transactionCreate">
...
    {{>transactionAlert}}
</template>
Template.transactionAlert.onCreated(function transactionAlertOnCreated() {
    console.log('test')
})

Template.transactionAlert.helpers({
    maxCost(){
        console.log('test 2')
        const instance = Template.instance()
        return instance.maxTxCost.get().toString().slice(0,5);
    }
})

person Carlos Hernandez    schedule 25.03.2019    source источник


Ответы (1)


Я попытался использовать вспомогательную функцию родительского шаблона.

Такие проблемы часто вызваны проблемами дизайна, а не отсутствием или неправильной реализацией. Если мы считаем, что ваш transactionAlert не имеет состояния (он не содержит какой-либо соответствующей логики представления или внутреннего управления состоянием), то он также не должен обращаться ни к свойствам, ни к помощникам, которые находятся вне его области.

В противном случае вы создадите такую ​​тесную связь, что она бросится вам в глаза через два года или около того (когда начнется сеанс рефакторинга).

Напротив, обязанности родительского шаблона заключаются в том, чтобы

  • управлять состоянием данных (подписки, постобработка данных и т.д.)
  • проверьте условия, должно ли transactionAlert появиться или исчезнуть
  • передать правильные параметры в шаблон transactionAlert

Как следствие, вы можете создать оповещение о транзакции в виде параметризованного шаблона:

<template name="transactionAlert">
...
<div class="mdc-dialog__content" ><p>Are you sure you wish to continue with this transaction? It could cost up to: <b class="warning-value">${{maxCost}} USD</b></p>
...
</template> 

Как видите, выглядит точно так же. Разница в том, что вы удаляете Template.transactionAlert.helpers и заставляете шаблон искать maxCost, передаваемый в шаблон.

Теперь в вашем родительском шаблоне вы передадите данные в transactionalert, как только будет применено условие для оповещения:

<template name="transactionCreate">
  {{#if showAlert}}
    {{>transactionAlert maxCost=getMaxCost}}
  {{/if}}
</template>

где помощник сейчас:

Template.transactionCreate.helpers({
    showAlert () {
      return Template.instance().showAlert.get()
    },
    getMaxCost(){
      const instance = Template.instance()
      return instance.maxTxCost.get().toString().slice(0,5);
    }
})

Поскольку вам нужна реактивность, чтобы показать/скрыть предупреждение, вы будете использовать внутренний трекер шаблона:

Template.transactionCreate.onCreated(function () {
  const instance = this
  instance.showAlert = new ReactiveVar(false)
  instance.autorun(() => {
    const maxCost = instance.maxTxCost.get()
    if (/* max cost exceeds limit */) {
      instance.showAlert.set(true)
    } else {
      instance.showAlert.set(false)
    } 
  })
})

Изменить: дополнительная информация о реактивности

Реактивность — основная концепция клиентской экосистемы Meteor. Он основан на пакете Tracker, который связан с любым экземпляром Template. Руководство по реактивным хранилищам данных объясняет концепцию немного подробнее: https://guide.meteor.com/data-loading.html#stores

person Jankapunkt    schedule 26.03.2019
comment
Спасибо, красиво получилось. Не могли бы вы объяснить, что делает автозапуск / как он работает? Является ли это эффективным, хорошей практикой и т. д. - person Carlos Hernandez; 26.03.2019
comment
Добавил несколько полезных ссылок в конец ответа. - person Jankapunkt; 26.03.2019
comment
В итоге я не использовал ни автозапуск, ни вспомогательную функцию showAlert. Хотя сейчас вроде работает. Есть ли причина держать его в себе? - person Carlos Hernandez; 26.03.2019
comment
Сохраните его, если он должен автоматически реагировать на изменения данных. - person Jankapunkt; 26.03.2019