同步相同 Ember 组件的多个实例的状态

Sync the states of multiple instances of same Ember Component

情况如下:

我编写了一个组件 facility-search 来搜索一些夹具数据。我将 {{facility-search}} 的多个实例放在同一个模板(标签页)上。该组件有一些输入框,我们可以在其中输入搜索关键字。我想观察输入框值的变化并将其更新到组件的另一个实例,以便它们都同步。

这就是我在 components/facility-search.js

中所做的
import Ember from 'ember';
import Em from 'ember';

var FacilitySearchComponent = Ember.Component.extend({

  // Tag name appears in HTML
  tagName: 'div',

  // RandomNumber
  searchBoxId: null,

  // All Facilities
  allFacilities: null,

  // Search Values
  textFacility: "",
  textCountry: "",
  textSpecies: "",

  // Text Input Ids needed for <label for="id"/>
  // Elements in multuple components should not have same id
  textFacilityId: 'text-facility',
  textCountryId: 'text-country',
  textSpeciesId: 'text-species',

  // Initialize Ids
  randomNumber: function(){
    this.set('searchBoxId',(Math.floor(Math.random() * 100) + 1));
    this.set('textFacilityId', this.get('textFacilityId') + "-" + this.get('searchBoxId'));
    this.set('textCountryId', this.get('textCountryId') + "-" + this.get('searchBoxId'));
    this.set('textSpeciesId', this.get('textSpeciesId') + "-" + this.get('searchBoxId'));
  }.on('init'),

  // When component is inserted
  didInsertElement: function() {
    this.set('filteredFacilities', this.get('allFacilities'));
  },

  // Observe Search Values
  watchForFilterChanges: function() {
    this.filterResults();
  }.observes('textFacility', 'textCountry', 'textSpecies'),

  // Filter Data
  filterResults: function() {
    var facilities = // Some mechanism to filter data
    self.sendAction('updateFacilities', facilities);
  }.on('allFacilities'),

  actions: {
    clearSearch: function() {
      this.set('textFacility', null);
      this.set('textCountry', null);
      this.set('textSpecies', null);
      this.filterResults();
    },

  }
});

export default FacilitySearchComponent;

这是我的templates/components/facility-search.hbs

<div class="card">
  <div class="card-content directory-search">
    <div class="card-title grey-text text-darken-3">
      <h4>Search Facilities</h4>
      <h4><small class="teal-text">{{filteredFacilities.length}} total</small></h4>
    </div>
    <form {{action "textSearch" this on="submit" data="lol"}}>
      <div class="row">
        <div class="input-field col s12">
          <label for="{{textFacilityId}}">Search by facility</label>
          {{input value=textFacility type="text" id=textFacilityId label="Facility Name"}}
        </div>
        <div class="input-field col s12">
          <label for="{{textCountryId}}">Search by country</label>
          {{input value=textCountry type="text" id=textCountryId label="Facility Country"}}
        </div>
        <div class="input-field col s12">
          <label for="{{textSpeciesId}}">Search by species</label>
          {{input value=textSpecies type="text" id=textSpeciesId label="Facility Species"}}
        </div>
      </div>
    </form>
    <a {{action 'clearSearch'}} class="waves-effect waves-light btn"><i class="material-icons right">clear_all</i>clear search</a>
  </div>
</div>

这是我的controllers/map.js

import Ember from 'ember';
import pagedArray from 'ember-cli-pagination/computed/paged-array';

export default Ember.Controller.extend({

  // Facility to be shown in modal
  selectedFacility: null,

  // Facilities to be shown in search
  filteredFacilities: [],

  // Initialize filteredFacilities to model
  initializeFacilities: function() {
    this.set('filteredFacilities', this.get("model"));
  }.observes('model'),

  actions: {
    showFacilityInModal: function(facility){
      this.set('selectedFacility', facility);
    },
    updateFacilities: function(facilities){
      this.set('filteredFacilities', facilities);
    },
  }
});

这是routes/map.js

import Ember from 'ember';

export default Ember.Route.extend({
    model: function() {
        return this.store.find('facility');
    },
});

这就是我在 templates/map.hbs

中使用组件的方式
{{facility-search allFacilities=model updateFacilities='updateFacilities'}}

我了解到,如果我们多次放置组件;它将有完整的新实例。因此在同一组件的另一个实例中无法观察到更新变量 textFacility 和其他变量。但我也想在另一个实例中更新这些值。知道我们如何同步同一组件的多个实例的状态吗?

我找到了解决方法!!不确定这样做是否正确。

我把变量textCountry放在controllers/map.js中,然后传给组件如下:

{{facility-search textCountryComponentSpec=textCountry allFacilities=model updateFacilities='updateFacilities'}}

其中 textCountryComponentSpec 在组件中保存该值。然后我观察了组件中 textCountryComponentSpec 的变化并更新了控制器中的 textCountry 。由于它被传递给组件,因此它反映了更改。

如果你知道更好的方法请post。

如果我理解你想在所有组件之间共享值,那么如果你改变一个组件,它也会在另一个组件中改变。

你可以这样做:

  text : {
    facility: "",
    country: "",
    species: "",
  }

而不是

  textFacility: "",
  textCountry: "",
  textSpecies: "",

将其声明为对象意味着它将像静态变量一样在所有组件实例中共享。