0

Вот ситуация:Синхронизировать состояния нескольких экземпляров одного Ember компонент

я написал компонент 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 и других не наблюдается в другом экземпляре того же компонента. Но я хочу обновить эти значения и в другом экземпляре. Любая идея, как мы можем синхронизировать состояния нескольких экземпляров одного и того же компонента?

ответ

1

Если я понимаю, что вы задаете вопрос, вы хотите делиться значениями между всеми компонентами, поэтому, если вы меняете его на один, он изменяется в другом.

Вы можете сделать это:

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

вместо

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

Декларирования как объект означает, что он будет акциями во всех экземплярах компонентов, как статические переменные.

0

Я нашел обходное решение !! Не уверен, что это правильный способ сделать это.

Я ставлю переменные textCountry в controllers/map.js и передал его компонент следующим образом:

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

где textCountryComponentSpec считает, что значение в компоненте. Затем я наблюдал изменения в textCountryComponentSpec в компоненте и обновлял textCountry в контроллере. Поскольку он передается компонентам, он отражает изменения.

Если вы знаете лучший способ, пожалуйста, отправьте сообщение.

Смежные вопросы