我将Ember.js与Ember-cli和Ember data一起使用。到目前为止,开发进展相当顺利,但现在我遇到了css转换的问题,我自己无法解决。
我有一份清单。该列表包含具有子元素的元素。这些子元素也被呈现为列表。
我从一个RESTneneneba API获取带有member-data的数据。收到数据后,我想淡入(css不透明)列表。但这并不正确。有时会显示过渡,有时则不会。恐怕是时间问题。所以我在代码中添加了Ember.run.next,但它没有帮助。当我在Ember.run.next中添加带有1ms的setTimeout时,它的工作方式与预期的一样(至少在我的计算机上)。这感觉很奇怪。这是我迄今为止的代码。感谢所有反馈。
controller.js:
export default Ember.Controller.extend({
//...
objects: []
//...
_pushToMatchings: function (response) {
var tempArray = [];
var pushed = false;
for (var i = 0, length = this.get('objects.length'); i < length; i++) {
pushed = false;
var match = this.get('objects').objectAt(i);
if (match.get('meta.items').objectAt(0) === response.get('meta.items').objectAt(0)) {
tempArray.pushObject(response);
pushed = true;
} else {
tempArray.pushObject(match);
}
}
if (!pushed) {
tempArray.pushObject(response);
}
this.set('objects', tempArray);
},
fetch: function() {
var self = this;
// find parent item
this.get('store').find('item', id).then(function (item) {
self._pushToMatchings(Ember.Object.create({
meta: {
items: [id],
isLoading: true,
label: item.get('label')
},
content: []
}));
self.set('isOpen', true);
// child object
self.get('store').find('child', searchParams).then(function (result) {
(function (resultPtr) {
Ember.run.next(function () {
setTimeout(function () { // @todo why do we need timeout here? whitout there is no fade out with opacity in css possible
resultPtr.set('meta.isLoaded', true);
}, 1); // 1 is enough but give spinner some time otherwise it looks ugly
});
}(result));
result.set('meta.label', item.get('label'));
self._pushToMatchings(result);
}, function (error) { /* ... */ });
}, function (error) { /* ... */ });
}
}
控制器.hbs:
<div>
{{item-list close="close" elements=objects }}
</div>
item-list.js
export default Ember.Component.extend({
elements: [],
actions: {
close: function () {
this.sendAction('close');
}
}
});
项目列表.hbs
<div class="items-list__buttons">
<i class="icon-close_32" {{action "close" }}></i>
</div>
<div class="items-list__content">
{{#each matching in elements}}
<div class="items-list__item">
<h2>{{t "items.offers" }} {{matching.meta.label}}</h2>
{{spinner-element hideEvent=matching.meta.isLoaded }}
<div {{bind-attr class=":items-list__box matching.meta.isLoaded:items--fadeIn" }}>
{{#each item in matching.content}}
<div>
<!-- Render details of item -->
</div>
{{/each}}
</div>
</div>
{{/each}}
</div>
CSS:
.items-list__box {
opacity: 0;
transition: opacity 150ms ease 100ms;
}
.items--fadeIn {
opacity: 1;
}
您可以使用Ember.run.later,其工作方式与setTimeout相同。
Ember.run.later(this ,function(){
resultPtr.set('meta.isLoaded', true);
}, 100);
我不确定,但这是必要的,因为div将用类"items-fadeIn"呈现,这样就不会发生转换。我已经这样做了,并为我工作,只是试着增加一点时间。
我知道这是一个迟来的答案,但对于其他收到类似问题的人来说:
您的问题是,Ember正在重新呈现{{#each
中的整个项目列表,因为每次某个东西发生变化时,您都会给它一个全新的对象数组,而不是更改数组中对象的属性。您需要做的是定义对象数组并操作它们的属性,以便只有更改的对象才能重新渲染。