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

时间:2015-07-08 19:49:45

标签: ember.js ember-data ember-cli ember-controllers ember-components

以下是这种情况:

我写了一个组件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和其他变量。但是我想在另一个实例中更新这些值。知道我们如何同步相同组件的多个实例的状态吗?

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你想在所有组件之间共享值,所以如果你在一个组件中更改它,它会在另一个组件中发生变化。

你可以这样做:

innerHTML

而不是

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

将其声明为对象意味着它将是所有组件实例的共享,如静态变量。

答案 1 :(得分:0)

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

我将变量textCountry放入controllers/map.js并将其传递给组件,如下所示:

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

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

如果你知道更好的方式,请发帖。