JQuery and Reactive Meteor Components

2019-07-15 06:33发布

问题:

I am using jquery steps in order to render a wizard within a Blaze template.

js:

Template.form.onRendered( function () {
    var form = $("#form1");
    form.children("div").steps({
        headerTag: "h4",
        bodyTag: "fieldset",
        transitionEffect: "slideLeft"
    })
})

Template.form.helpers({
   person : function () {
      return People.find();
   },
})

html :

<template name="form">
   <form id="form1">
    <div>
        <h4>1</h4>
        <fieldset>
            <small>First Step</small>
        </fieldset>

        <h4>2</h4>
        <fieldset>
            <small>Second Step</small>
        </fieldset>

        <h4>3</h4>
        <fieldset>
            <small>Third Step</small>
        </fieldset>

        <h4>4</h4>
        <fieldset>
            {{#each person}}
                {{this.name}}    
            {{/each}}
        </fieldset>
    </div>
  </form>
</template>

On the 4th step all of the people that are in the collection when the jquery steps get rendered and created are shown. However if I add people while on the 4th step they do not get added until I refresh the page and the jquery step gets rebuilt. Is there someway to make the jquery step html reactive?

回答1:

Yes, this is a very common pattern when working with additional JS libraries for UI components. The typically chosen solution is to structure your code/template such that there will be another onRendered event when new things get added. In your case you might do:

  <h4>4</h4>
  <fieldset>
    {{#each person}}
    {{> person}}
    {{/each}}
  </fieldset>

...

<template name="person">
  {{name}}
</template>

And have the same onRendered function for that template:

function render() {
    var form = $("#form1");
    form.children("div").steps({
        headerTag: "h4",
        bodyTag: "fieldset",
        transitionEffect: "slideLeft"
    })
}

Template.form.onRendered( render );
Template.person.onRendered( render );


回答2:

What ended up working for me:

js:

Template.form.onRendered( function () {
    var form = $("#form1");
    form.children("div").steps({
        headerTag: "h4",
        bodyTag: "fieldset",
        transitionEffect: "slideLeft"
    })

    // New Addition
    var temp = this;
    Blaze.render(
        Template.allPeople,
        temp.$('#reactiveUI').get(0)
    );
})

Template.allPeople.helpers({
   person : function () {
       return People.find();
   },
})

html:

<template name="form">
  <form id="form1">
    <div>
     <h4>1</h4>
     <fieldset>
        <small>First Step</small>
     </fieldset>

    <h4>2</h4>
    <fieldset>
        <small>Second Step</small>
    </fieldset>

    <h4>3</h4>
    <fieldset>
        <small>Third Step</small>
    </fieldset>

    <h4>4</h4>
    <fieldset>
       <div id="reactiveUI">
          <!--Insert Reactive HERE-->
       </div>
    </fieldset>
  </div>
 </form>

<template name="allPeople">
   <ul>
      {{#each person}}
        <li>{{this.type}}</li>
      {{/each}}
   </ul>
</template>

Now after the jquery steps gets built I inject the reactive Blaze template, rather than injecting it before the jquery steps does its thing. Notice the Blaze.render in the onRendered function.