Ember控制器中的操作处理出现问题。我想在hbs中点击编辑按钮后继续运行一些功能。我已经试过了。
openEditWindow() {
this.set('someChangingValue', true);
},
以下是对动作someChangingValue
变化作出反应的函数。
someChangingValue: false,
someTestFunction: observer('someChangingValue', function() {
var test = this.get('someChangingValue');
if(test === true){
Ember.run.later((function() {
this.functionThatIsRunningEachTwoSeconds();
}), 2000);
} else {
console.log('this should not do anything');
}
}),
但这只运行functionThatIsRunningEachTwoSeconds
一次。还尝试了同样的功能,将someChangingValue
更改为false
(如果是true
,则为CCD_5),否则,这将使我处于观察属性的无限循环中。
谢谢!
Ember.run.later
只运行一次函数。文件中说得很清楚
另外,你用的是旧版本的烬吗?Ember.run.later
已经过时,您应该使用部分导入import { later } from '@ember/runloop';
而不是
至于你的任务,至少有两种方法
使用ember并发插件
安装成员并发并写入控制器:
import { task, timeout } from 'ember-concurrency';
export default Controller.extend({
infiniteTask: task(function* () {
while(true) {
this.functionThatIsRunningEachTwoSeconds();
yield timeout(2000);
}
}).drop(),
});
模板:
{{#if infiniteTask.isIdle}}
<button onclick={{perform infiniteTask}}>Start</button>
{{else}}
<button onclick={{cancel-all infiniteTask}}>Stop</button>
{{/if}}
这个插件在很多情况下都很有用,阅读它的文档可以理解为什么你可能需要它
创建一个递归调用自身的函数
这是一种经典的JS方法来重复一些操作,但在普通JS中,我们使用setTimeout
而不是ember的later
。
import { later, cancel } from '@ember/runloop';
export default Controller.extend({
infiniteFuction() {
this.functionThatIsRunningEachTwoSeconds();
this.set('infiniteTimer', later(this, 'infiniteFuction', 2000));
},
startInfiniteFunction() {
//clear timer as safety measure to prevent from starting few
//"infinite function loops" at the same time
cancel(this.infiniteTimer);
this.infiniteFuction();
},
stopInfiniteFunction() {
cancel(this.infiniteTimer);
this.set('infiniteTimer', undefined);
}
});
模板:
{{#unless infiniteTimer}}
<button onclick={{action startInfiniteFunction}}>Start</button>
{{else}}
<button onclick={{action stopInfiniteFunction}}>Stop</button>
{{/unless}}
为了澄清当前代码的问题(不一定要将其作为解决方案),您必须更改要激发的观察者的值。如果您将该值设置为true
,然后在没有将其设置为CCD13的情况下再次将其设置成true
,Ember将在内部忽略这一点,并且不会重新设置观察器。请参阅此旋转以查看使用观察者的工作示例。
代码是
init(){
this._super(...arguments);
this.set('count', 0);
this.set('execute', true);
this.timer();
},
timer: observer('execute', function(){
//this code is called on set to false or true
if(this.get('execute')){
Ember.run.later((() => {
this.functionThatIsRunningEachTwoSeconds();
}), 2000);
// THIS IS SUPER IMPORTANT, COMMENT THIS OUT AND YOU ONLY GET 1 ITERATION
this.set('execute', false);
}
}),
functionThatIsRunningEachTwoSeconds(){
let count = this.get('count');
this.set('count', count + 1);
this.set('execute', true);
}
既然你知道你目前的方法有什么问题,让我再次记录下来,并指出这不是一个很好的、直观的方式来安排重复循环。我也推荐Ember并发,因为它是Ember生命周期感知
如果你处理了路线中的编辑按钮,你可以在路线更改时超级干净地取消它
functionThatIsRunningEachTwoSeconds: task(function * (id) {
try {
while (true) {
yield timeout(2000);
//work function
}
} finally {
//if you wanted code after cancel
}
}).cancelOn('deactivate').restartable()
停用对应成员停用路由挂钩/事件:
当路由器完全退出此路由时,将执行此挂钩。它当路线的模型改变时不执行。