How to access nested template attributes?

2019-04-01 19:05发布

问题:

I successfully implemented a form with quill wysiwyg but now I want to create a component to reuse it. This is my working implementation:

<template name="form">
  <form>
    <div id="toolbar"> ... html with toolbar buttons </div>
    <div id="editor"></div>
    <input type="submit" value="save"/>
  </form>
</template>
Template.form.rendered = function () {
  this.quill = new Quill('#editor', { 
    modules: {
     'toolbar': { container: '#toolbar' },
     'link-tooltip': true
    },
    theme: 'snow' }
  );
}

Template.form.events({
  'submit form': function(e, tmpl) {
    e.preventDefault();
    var html = tmpl.quill.getHTML();
    // code to save the form data
}

This is what I want to make it reusable. My questions are inside the code:

<template name="form">
  <form>
    {{> editor }}
    <input type="submit" value="save"/>
  </form>
</template>

<template name="editor">
  <div id="toolbar"> ... html with toolbar buttons </div>
  <div id="editor"></div>
</template>
Template.editor.rendered = function () {
  this.quill = new Quill('#editor', { 
    modules: {
     'toolbar': { container: '#toolbar' },
     'link-tooltip': true
    },
    theme: 'snow' }
  );

  // How can I pass quill to the parent template?

}

Template.form.events({
  'submit form': function(e, tmpl) {
    e.preventDefault();

    // How can I access quill variable on the nested template, so I can 
    // call quill.getHTML()?

}

回答1:

Here's a pattern I use to solve this sort of problem. Define a class called Editor and a template editor. The intention is that the data context inside editor will be an instance of Editor.

function Editor() {
  this.quill = null;
}

Template.editor.rendered = function () {
  this.data.quill = new Quill(...);
}
<template name="editor">...</template>

Inside form's created callback, create an Editor and store it on the template instance. Then when you call out to the editor template, pass in the Editor instance as the data context.

Template.form.created = function () {
  this.editor = new Editor();
}

Template.form.helpers({
  editorInstance: function () {
    return Template.instance().editor;
  }
});
<template name="form">
  <form>
    {{> editor editorInstance }}
    <input type="submit" value="save"/>
  </form>
</template>

You can then define methods on the Editor prototype which can be called by the form:

Editor.prototype.getTextAsHTML = function () {
  return this.quill && this.quill.getHTML();
}

Template.form.events({
  "submit form": function(e, tmpl) {
    e.preventDefault();
    var html = tmpl.editor.getTextAsHTML();
    // ...
  }
}

This is a nice way to abstract the details of the editor so that the form doesn't need to know about it. You can reuse the editor and if you ever want to change it, you just have to make sure getTextAsHTML works the same.



标签: meteor quill