同步相同 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: "",
将其声明为对象意味着它将像静态变量一样在所有组件实例中共享。
情况如下:
我编写了一个组件 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: "",
将其声明为对象意味着它将像静态变量一样在所有组件实例中共享。