是否可以使路线模型成为计算/跟踪模型 属性?
Is it possible to make a route's model a computed / tracked property?
我正在尝试让路由的模型挂钩 return 一些数组,该数组使用 Ember later
通过轮询机制不断更新。路由文件如下所示:
export default class IndexRoute extends Route {
recent: [],
init() {
...
this.getRecent();
}
getRecent() {
// poll data / fetch latest
this.recent.push(newStuff);
later(this, this.getRecent, 2000);
}
model() {
return this.recent;
}
}
然后在我的控制器中,我想根据路由的 model
:
创建一个 @computed
/ @tracked
属性
export default class IndexController extends Controller {
// @tracked model; // this also didn't work
@computed('model.@each') // this doesn't work
get computedModel() {
console.log('computedModel'); // prints only once, when the model hook is first run
return this.model;
}
}
我认为 的建议会起作用,但它没有 :(
我看到了 但这是针对 Ember 1.13 的,所以不完全是现代解决方案。
同样 this post 也有过时的内容。
我想做的事情可行吗?或者,我正在考虑将数据移动到 Controller 中,而不是对 Controller 变量进行计算 属性 。采纳所有建议!
您当前方法的根本问题是您没有使用 Ember Array 特定功能。当您在 Ember 中创建数组时,通常会发生一些神奇的事情,这些数组会自动将它们创建为 Ember 数组(至少在使用带有 .create
的旧式语法和原型时允许扩展)。您始终可以显式创建一个 Ember 数组:
import { A } from '@ember/array';
export default class ApplicationRoute extends Route{
recent = A([]);
}
无论如何,当您只使用 this.recent.push(newStuff);
时,此原生数组原型并未以 Ember 的 tracking/observer 系统可以知道新值已被使用的方式进行检测添加到 this.recent
并随后触发重新渲染。这既适用于跟踪属性,也适用于 Octane 之前的传统观察者系统。
相反,当与模板中显示的数组(即需要观察的数组)交互时,您必须使用特殊的Ember.Array
特定函数pushObject
,如this.recent.pushObject(newStuff)
。
getRecent() {
// poll data / fetch latest
this.recent.pushObject(this.current);
this.current = this.current + 1;
later(this, this.getRecent, 2000);
}
如果您想完全使用跟踪 属性 样式,可以避免使用 Ember 数组,但您必须通过将数组重新分配给跟踪 属性 来强制重新计算.这是组件中的示例
import Component from '@glimmer/component';
import { tracked} from '@glimmer/tracking';
import { later } from '@ember/runloop';
export default class extends Component {
@tracked
trackedArray = [];
current = 0;
constructor(){
super(...arguments);
this.doPoll();
}
doPoll() {
// essentially pushing but via a reassign with the new element
// you could also `pushObject` here if that feels better
this.trackedArray = [...this.trackedArray, this.current];
this.current = this.current + 1;
later(this, this.doPoll, 2000);
}
}
这里有一个 Ember Twiddle 显示了两种方法的实际应用。
PS。路由的 model
属性 只是准动态的。在过渡期间,model
挂钩的 return 值自动分配给路由的 currentModel
属性。然后这个值作为第二个参数传递到 setupController
并自动分配给控制器的 model
属性 如果没有定义 setupController
或者如果 setupController
调用 super
的基本实现。当为特定路由调用 modelFor
时,currentModel
属性 被 returned 并且 model
不会被重新调用。这就是说,在 model
函数中进行轮询本身不会自动更新控制器的 model
属性。在您的示例中一切正常,因为 model
引用永远不会改变(您只是在改变数组)。
我正在尝试让路由的模型挂钩 return 一些数组,该数组使用 Ember later
通过轮询机制不断更新。路由文件如下所示:
export default class IndexRoute extends Route {
recent: [],
init() {
...
this.getRecent();
}
getRecent() {
// poll data / fetch latest
this.recent.push(newStuff);
later(this, this.getRecent, 2000);
}
model() {
return this.recent;
}
}
然后在我的控制器中,我想根据路由的 model
:
@computed
/ @tracked
属性
export default class IndexController extends Controller {
// @tracked model; // this also didn't work
@computed('model.@each') // this doesn't work
get computedModel() {
console.log('computedModel'); // prints only once, when the model hook is first run
return this.model;
}
}
我认为
我看到了
同样 this post 也有过时的内容。
我想做的事情可行吗?或者,我正在考虑将数据移动到 Controller 中,而不是对 Controller 变量进行计算 属性 。采纳所有建议!
您当前方法的根本问题是您没有使用 Ember Array 特定功能。当您在 Ember 中创建数组时,通常会发生一些神奇的事情,这些数组会自动将它们创建为 Ember 数组(至少在使用带有 .create
的旧式语法和原型时允许扩展)。您始终可以显式创建一个 Ember 数组:
import { A } from '@ember/array';
export default class ApplicationRoute extends Route{
recent = A([]);
}
无论如何,当您只使用 this.recent.push(newStuff);
时,此原生数组原型并未以 Ember 的 tracking/observer 系统可以知道新值已被使用的方式进行检测添加到 this.recent
并随后触发重新渲染。这既适用于跟踪属性,也适用于 Octane 之前的传统观察者系统。
相反,当与模板中显示的数组(即需要观察的数组)交互时,您必须使用特殊的Ember.Array
特定函数pushObject
,如this.recent.pushObject(newStuff)
。
getRecent() {
// poll data / fetch latest
this.recent.pushObject(this.current);
this.current = this.current + 1;
later(this, this.getRecent, 2000);
}
如果您想完全使用跟踪 属性 样式,可以避免使用 Ember 数组,但您必须通过将数组重新分配给跟踪 属性 来强制重新计算.这是组件中的示例
import Component from '@glimmer/component';
import { tracked} from '@glimmer/tracking';
import { later } from '@ember/runloop';
export default class extends Component {
@tracked
trackedArray = [];
current = 0;
constructor(){
super(...arguments);
this.doPoll();
}
doPoll() {
// essentially pushing but via a reassign with the new element
// you could also `pushObject` here if that feels better
this.trackedArray = [...this.trackedArray, this.current];
this.current = this.current + 1;
later(this, this.doPoll, 2000);
}
}
这里有一个 Ember Twiddle 显示了两种方法的实际应用。
PS。路由的 model
属性 只是准动态的。在过渡期间,model
挂钩的 return 值自动分配给路由的 currentModel
属性。然后这个值作为第二个参数传递到 setupController
并自动分配给控制器的 model
属性 如果没有定义 setupController
或者如果 setupController
调用 super
的基本实现。当为特定路由调用 modelFor
时,currentModel
属性 被 returned 并且 model
不会被重新调用。这就是说,在 model
函数中进行轮询本身不会自动更新控制器的 model
属性。在您的示例中一切正常,因为 model
引用永远不会改变(您只是在改变数组)。