【发布时间】:2017-05-27 18:38:22
【问题描述】:
在 Ember js 中有一个有趣的问题。
下面是组件advanced-search/component.js,具有两个计算属性roomType 和room,依赖于服务services/advanced-searchqueryObj.{roomId,roomTypeId} 对象属性。
当从模板中选择一个选项时,roomType 计算属性会触发并正确更新模板。然而,有趣的是,当从模板中选择房间时,room 计算属性无法触发。我通过在 room 计算属性中放置 console.log('checking room computed fired') 来验证这一点。
为了进一步探索这个异常,我做了以下事情:
- 我取消了您在
init方法中看到的代码的注释,该方法设置了填充房间列表下拉列表的rooms数组,并在最初设置@987654333 的setRoomType操作方法内的操作哈希中注释了代码@ 大批。在这些更改之后,room计算属性会正确触发并更新模板。 - 我注意到
this.get('store).findAll('roomType')返回的数组导致roomType计算属性正确触发并更新模板,因此我尝试将setRoomType中对rooms的调用从roomType.get('rooms')更改为@ 987654340@ 看看它是否也导致room计算属性正确触发,但它仍然NOT 触发room计算属性。因此,我得出结论,roomType和room计算属性只有在组件的init方法中设置了它们的下拉列表数组时才能正确触发和更新模板。
高级搜索/component.js
export default Ember.Component.extend({
advancedSearch: Ember.inject.service('advanced-search'),
queryObj: Ember.computed.alias('advancedSearch.queryObj'),
init() {
this._super(...arguments);
// I believe because the 'roomTypes` array is set in this init method, the 'roomType' computed property fires correctly and updates the template
this.get('store').findAll('roomtype').then((roomTypes) => {
this.set('roomTypes', roomTypes);
});
// When the 'rooms' array is also initialized here, the 'room' computed property fires successfully on 'room' selection from the dropdown and updates the template
// this.get('store').findAll('room').then((rooms) => {
// this.set('rooms', rooms);
// });
},
roomTypes: [],
roomType: Ember.computed('queryObj.{roomTypeId}', function() {
var that = this;
return this.get('roomTypes').find(function(roomType) {
return that.get('queryObj').roomTypeId === roomType.id;
});
}),
rooms: [],
room: Ember.computed('queryObj.{roomId}', function() {
console.log('checking room computed fired')
var that = this;
return this.get('rooms').find(function(room) {
return that.get('queryObj').roomId === room.id;
});
}),
actions: {
setRoomType(roomType) {
this.get('advancedSearch').setRoomType(roomType);
this.set('room', null);
if (roomType) {
// When rooms array initialized from here the room computed property fails to fire on room selection from drop down
roomType.get('rooms').then((rooms) => {
this.set('rooms', rooms);
});
} else {
this.set('rooms', null);
}
},
setRoom(room) {
this.get('advancedSearch').setRoom(room);
}
}});
下面是服务代码:
服务/高级搜索
export default Ember.Service.extend({
queryObj: {},
setRoomType(roomType) {
this.set('queryObj.roomTypeId', roomType.id);
},
setRoom(room) {
this.set('queryObj.roomId', room.id);
}});
下面是组件模板:
高级搜索/template.hbs
<div class="col-md-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3>Advanced Search</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-2">
{{#power-select placeholder="Room type" allowClear=true selected=roomType options=roomTypes onchange=(action "setRoomType") as |roomType| }} {{roomType.name}} {{/power-select}}
</div>
<div class="col-md-2">
{{#power-select placeholder="Room No" allowClear=true selected=room options=rooms onchange=(action "setRoom") as |room| }} {{room.name}} {{/power-select}}
</div>
</div>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
注意:我希望通过“roomType”模型的名为“rooms”的关系属性从操作方法“setRoomType”设置“rooms”属性,以便始终根据选择的“roomType”过滤房间.
我们将不胜感激。
Ember 版本:
- Ember Inspector 2.0.4
- Ember 2.8.2
- Ember 数据 2.9.0
- jQuery 3.1.1
- Ember 简单身份验证 1.1.0
【问题讨论】:
标签: javascript ember.js