简体   繁体   中英

How can I prevent Meteor from re-rendering view on html select dom click event when I believe it should not be re-rendering the view?

I have a form in my Meteor application that when I populate and re-populate the html select options the view re-renders and removes the input values the user typed into the form. I don't believe this is correct.

Client Form

 <form class="form-horizontal well" id="insert-form">
    <fieldset>

      <div class="control-group">
        <label class="control-label" for="username">User Name</label>
        <div class="controls">
          <input type="text" class="input-xlarge" id="username" name="username">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="password">Password</label>
        <div class="controls">
          <input type="password" class="input-xlarge" id="password" name="password">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="email">Email</label>
        <div class="controls">
          <input type="text" class="input-xlarge" id="email" name="email">
        </div>
      </div>
      <div class="control-group">
        <label class="control-label" for="country">Country</label>
        <div class="controls">
          <select class="input-xlarge country" id="country" name="country">
             <option value="">Select a country...</option>
            {{#each get_countries}}
              <option value="{{iso3}}" {{is_country_selected iso3}}>{{name}}</option>
            {{/each}}
          </select>
        </div>
      </div>

      {{#if state_label}}
        <div id="div-state" class="control-group">
          <label class="control-label" for="state">{{state_label}}</label>
          <div class="controls">
            <select class="input-xlarge country" id="state" name="state">
             <option value="">Select a {{state_label}}...</option>
            {{#each get_states}}
              <option value="{{code}}" {{is_state_selected code}}>{{name}}</option>
            {{/each}}
          </select>
          </div>
        </div>
      {{/if}}

      {{#if zip_code_label}}
      <div id="div-zip" class="control-group">
        <label class="control-label" for="zip">{{zip_code_label}}</label>
        <div class="controls">
          <input type="text" class="input-xlarge" id="zip" name="zip">
        </div>
      </div>
      {{/if}}
      <div class="form-actions well">
        <button id="btnReset" type="reset" class="btn btn-large">Reset</button>
        <button id="insert" type="button" class="btn btn-primary btn-large">Submit</button>
      </div>

    </fieldset>

Client Handlebars helper functions

Handlebars.registerHelper('state_label', function(){
  return Session.get('state_label');
});

Handlebars.registerHelper('zip_code_label', function(){
  return Session.get('zip_code_label');
});

Handlebars.registerHelper('is_country_selected', function(code){
  if(Session.get('country_selected') === code){
    return 'selected="selected"';
  }
});

Handlebars.registerHelper('is_state_selected', function(code){
  if(Session.get('state_selected') === code){
    return 'selected="selected"';
  }
});

/common/ client and server shared Countries model

Countries = new Meteor.Collection("countries");

Countries.get_countries = function(){
  return Countries.find({}, {fields: {iso3:1, name:1} }); //{}, {fields: {iso3:1,    name:1} }
}

Countries.get_states = function(code){
  return Countries.findOne( {iso3: code, 'states.active': true}, {fields:     {'states.code':1, 'states.name':1} } ).states;
}

Server Countries publish

Meteor.publish("countries", function() {
 if(this.userId()){

 return Countries.find(
  {
    active: true
  }, 
  {
    fields: {
      _id: 1,
      code: 1,
      name: 1,
      active: 1,
      iso3: 1,
      state_description: 1,
      zip_code_description: 1,
      zip_code_mask: 1,
      states: 1
     }
   }
  );

  } else {
  return null;
 }

 });   

Client Startup stuff

Meteor.startup(function () {
  Session.set('country_selected', 'USA');
  Session.set('state_label', 'State');
  Session.set('zip_code_label', 'Zip Code');
  Session.set('state_selected', 'FL');
 }); 

Server Startup stuff

Meteor.startup(function () {
if (Countries.find().count() === 0) {
console.log('[server/bootstrap.js] creating Countries');
var data = [
  {code: 'US',
   name: 'UNITED STATES',
   active: true,
   iso3: 'USA',
   state_description: 'State',
   zip_code_description: 'Zip Code',
   zip_code_mask: '99999',
   states: [
    {code: 'AL', name:'ALABAMA', active: true},
    {code: 'AK', name:'ALASKA', active: true},
    {code: 'AS', name:'AMERICAN SAMOA', active: true},
    {code: 'AZ', name:'ARIZONA', active: true},
    {code: 'AR', name:'ARKANSAS', active: true},
    {code: 'CA', name:'CALIFORNIA', active: true},
    {code: 'CO', name:'COLORADO', active: true},
    {code: 'CT', name:'CONNECTICUT', active: true},
    {code: 'DE', name:'DELAWARE', active: true},
    {code: 'DC', name:'DISTRICT OF COLUMBIA', active: true},
    {code: 'FL', name:'FLORIDA', active: true},
    {code: 'GA', name:'GEORGIA', active: true},
    {code: 'GU', name:'GUAM', active: true},
    {code: 'HI', name:'HAWAII', active: true},
    {code: 'ID', name:'IDAHO', active: true},
    {code: 'IL', name:'ILLINOIS', active: true},
    {code: 'IN', name:'INDIANA', active: true},
    {code: 'IA', name:'IOWA', active: true},
    {code: 'KS', name:'KANSAS', active: true},
    {code: 'KY', name:'KENTUCKY', active: true},
    {code: 'ME', name:'MAINE', active: true},
    {code: 'MD', name:'MARYLAND', active: true},
    {code: 'MA', name:'MASSACHUSETTS', active: true},
    {code: 'MI', name:'MICHIGAN', active: true},
    {code: 'MN', name:'MINNESOTA', active: true},
    {code: 'MS', name:'MISSISSIPPI', active: true},
    {code: 'MO', name:'MISSOURI', active: true},
    {code: 'MT', name:'MONTANA', active: true},
    {code: 'NE', name:'NEBRASKA', active: true},
    {code: 'NV', name:'NEVADA', active: true},
    {code: 'NH', name:'NEW HAMPSHIRE', active: true},
    {code: 'NJ', name:'NEW JERSEY', active: true},
    {code: 'NM', name:'NEW MEXICO', active: true},
    {code: 'NY', name:'NEW YORK', active: true},
    {code: 'NC', name:'NORTH CAROLINA', active: true},
    {code: 'ND', name:'NORTH DAKOTA', active: true},
    {code: 'MP', name:'NORTHERN MARIANA ISLANDS', active: true},
    {code: 'OH', name:'OHIO', active: true},
    {code: 'OK', name:'OKLAHOMA', active: true},
    {code: 'OR', name:'OREGON', active: true},
    {code: 'PA', name:'PENNSYLVANIA', active: true},
    {code: 'PR', name:'PUERTO RICO', active: true},
    {code: 'RI', name:'RHODE ISLAND', active: true},
    {code: 'SC', name:'SOUTH CAROLINA', active: true},
    {code: 'SD', name:'SOUTH DAKOTA', active: true},
    {code: 'TN', name:'TENNESSEE', active: true},
    {code: 'TX', name:'TEXAS', active: true},
    {code: 'UT', name:'UTAH', active: true},
    {code: 'VT', name:'VERMONT', active: true},
    {code: 'VI', name:'VIRGIN ISLANDS', active: true},
    {code: 'VA', name:'VIRGINIA', active: true},
    {code: 'WA', name:'WASHINGTON', active: true},
    {code: 'WV', name:'WEST VIRGINIA', active: true},
    {code: 'WI', name:'WISCONSIN', active: true},
    {code: 'WY', name:'WYOMING', active: true},
   ]
  },
  {code: 'CA',
   name: 'CANADA',
   active: true,
   iso3: 'CAN',
   state_description: 'Province',
   zip_code_description: 'Postal Code', 
   zip_code_mask: 'A9A 9A9',
   states: [
    {code: 'AB', name:'ALBERTA', active: true},
    {code: 'BC', name:'BRITISH COLUMBIA', active: true},
    {code: 'NB', name:'NEW BRUNSWICK', active: true},
    {code: 'NF', name:'NEWFOUNDLAND', active: true},
    {code: 'NT', name:'NORTHWEST TERRITORIES', active: true},
    {code: 'NS', name:'NOVA SCOTIA', active: true},
    {code: 'ON', name:'ONTARIO', active: true},
    {code: 'PW', name:'PALAU', active: true},
    {code: 'QC', name:'PQ QUEBEC', active: true},
    {code: 'PE', name:'PRINCE EDWARD ISLAND', active: true},
    {code: 'SK', name:'SASKATCHEWAN', active: true},
    {code: 'MB', name:'MANITOBA', active: true},
    {code: 'NU', name:'NUNAVUT', active: true},
    {code: 'YT', name:'YUKON', active: true},
   ]
  },
];

for (var i = 0; i < data.length; i++) {
  var country_id = Countries.insert({
    code: data[i].code,
    name: data[i].name,
    active: data[i].active,
    iso3: data[i].iso3,
    state_description: data[i].state_description,
    zip_code_description: data[i].zip_code_description,
    zip_code_mask: data[i].zip_code_mask,
    states: data[i].states
   });
   }
  }//end countries
});     

I believe based on the Meteor docs that this should not be happening. According to the docs as long as elements have a unique id and/or name then they should not be affected by updating DOM. I may be amiss on that though.

Any ideas why this might be happening?

Simple answer. I pulled the country, state and zip code divs out of the main template and put them in a sub-template and call them from the main template. Answer was found on...

https://github.com/oortcloud/unofficial-meteor-faq

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM