I'm using m.request in a project, and since I have a request that can be potentially long running, I want to run it with background:true
. However, it seems like the value never gets set to the generated m.prop
.
我使用m。请求在一个项目中,由于我有一个可能长时间运行的请求,我想用背景来运行它:true。然而,似乎这个值永远不会被设置为生成的m.p eop。
I've made a jsFiddle with an example based on this Stack Overflow answer: http://jsfiddle.net/u5wuyokz/9/
我根据这个堆栈溢出回答(http://jsfiddle.net/u5wuyokz/9/)做了一个例子
What I expect to happen is that the second call to the view should have the response value in ctrl.test.data()
, but it seems to still have undefined
. At Point A
in the code, it logs the correct value. However, at Point B
, it logs false, undefined
and then true, undefined
.
我预期的结果是,对视图的第二个调用应该在ctrl.test.data()中具有响应值,但它似乎仍然没有定义。在代码的A点,它记录正确的值。然而,在点B,它记录为false, undefined,然后true, undefined。
I'm not sure if I'm doing something incorrectly, or if this the expected behavior.
我不确定我做错了什么,或者这是预期的行为。
Code from the jsFiddle:
jsFiddle代码:
var requestWithFeedback = function(args) {
var completed = m.prop(false)
var complete = function(value) {
completed(true)
return value
}
args.background = true
return {
data: m.request(args).then(complete, complete).then(function(value) {
//Point A
console.log(value);
m.redraw()
return value
}),
ready: completed
}
};
var mod = {
controller : function() {
this.test = requestWithFeedback({
method : "POST",
url : "/echo/json/",
serialize: serialize,
config: asFormUrlEncoded,
data : {
json : "{\"name\" : \"testing\"}"
}
});
},
view : function(ctrl) {
//Point B
console.log(ctrl.test.ready(), ctrl.test.data());
return m("div", ctrl.test.ready() ? 'loaded' : 'loading');
}
};
2 个解决方案
#1
2
Edit: The problem is that m.redraw
is called before the data is assigned. Instead you could create a m.prop
for data
and let the ajax request assign that value when completed. requestWithFeedback
will then look like this:
编辑:问题是m。在分配数据之前调用redraw。相反,你可以创建一个m。保存数据并让ajax请求在完成时分配该值。requestWithFeedback会如下所示:
var requestWithFeedback = function(args) {
var data = m.prop()
args.background = true
m.request(args).then(data).then(function() { m.redraw() })
return {
data: data,
ready: function() {return !!data()}
}
};
Here's a modified version of your fiddle using this code: http://jsfiddle.net/u5wuyokz/11/
下面是修改后的小提琴版本,使用以下代码:http://jsfiddle.net/u5wuyokz/11/
#2
1
When using background: true
, Mithril's components branch or any other system that executes controllers in the same 'tick' as views, m.request
s made in the controller will not have resolved by the time they are invoked by their respective views.
当使用后台:true, Mithril的组件分支或任何其他系统执行控制器在同一'滴答'的视图,m。在控制器中发出的请求在被各自的视图调用时将不会得到解析。
It is therefore recommended to always use the initialValue
property of m.request
if you're using background: true
. The canonical example is to have an initial value of []
when you make a request for a list of entries:
因此,建议始终使用m的initialValue属性。如果你正在使用背景:true。典型的例子是,当您请求一个条目列表时,有一个[]的初始值:
var projectsModule = {
controller(){
this.projects = m.request( {
background : true,
initialValue : [],
url : '/projects.json'
} );
},
view( ctrl ){
return m( 'ul', ctrl.projects.map(
project => m( 'li', project.name )
) )
}
}
This solves the practical problems of views breaking when they expect to be able to work with m.request
return values in a generic way, but doesn't address the more complex case in your example, where a ready
flag is desirable to indicate a 'loading' state. I have a generic API that consumes a model getter function and an optional initial value. It has next
, then
, hasResolved
, isPending
, get
and set
methods: this allows views to be more flexible in the way they query the state of asynchronous models. hasResolved
indicates whether the method has ever resolved, and next
returns a promise that will resolve either with the current request, or when the next request is resolved if isPending
is false.
这就解决了实际问题,即当视图希望能够与m一起工作时,视图会被破坏。以通用的方式请求返回值,但不解决示例中更复杂的情况,即需要准备标志来指示“加载”状态。我有一个通用的API,它使用一个模型获取函数和一个可选的初始值。接下来,它有解析、ispend、get和set方法:这允许视图在查询异步模型状态的方式上更加灵活。hasresolve指示该方法是否已经解析,然后next返回一个承诺,该承诺将在当前请求中解析,或者在isPending为false时解析下一个请求。
#1
2
Edit: The problem is that m.redraw
is called before the data is assigned. Instead you could create a m.prop
for data
and let the ajax request assign that value when completed. requestWithFeedback
will then look like this:
编辑:问题是m。在分配数据之前调用redraw。相反,你可以创建一个m。保存数据并让ajax请求在完成时分配该值。requestWithFeedback会如下所示:
var requestWithFeedback = function(args) {
var data = m.prop()
args.background = true
m.request(args).then(data).then(function() { m.redraw() })
return {
data: data,
ready: function() {return !!data()}
}
};
Here's a modified version of your fiddle using this code: http://jsfiddle.net/u5wuyokz/11/
下面是修改后的小提琴版本,使用以下代码:http://jsfiddle.net/u5wuyokz/11/
#2
1
When using background: true
, Mithril's components branch or any other system that executes controllers in the same 'tick' as views, m.request
s made in the controller will not have resolved by the time they are invoked by their respective views.
当使用后台:true, Mithril的组件分支或任何其他系统执行控制器在同一'滴答'的视图,m。在控制器中发出的请求在被各自的视图调用时将不会得到解析。
It is therefore recommended to always use the initialValue
property of m.request
if you're using background: true
. The canonical example is to have an initial value of []
when you make a request for a list of entries:
因此,建议始终使用m的initialValue属性。如果你正在使用背景:true。典型的例子是,当您请求一个条目列表时,有一个[]的初始值:
var projectsModule = {
controller(){
this.projects = m.request( {
background : true,
initialValue : [],
url : '/projects.json'
} );
},
view( ctrl ){
return m( 'ul', ctrl.projects.map(
project => m( 'li', project.name )
) )
}
}
This solves the practical problems of views breaking when they expect to be able to work with m.request
return values in a generic way, but doesn't address the more complex case in your example, where a ready
flag is desirable to indicate a 'loading' state. I have a generic API that consumes a model getter function and an optional initial value. It has next
, then
, hasResolved
, isPending
, get
and set
methods: this allows views to be more flexible in the way they query the state of asynchronous models. hasResolved
indicates whether the method has ever resolved, and next
returns a promise that will resolve either with the current request, or when the next request is resolved if isPending
is false.
这就解决了实际问题,即当视图希望能够与m一起工作时,视图会被破坏。以通用的方式请求返回值,但不解决示例中更复杂的情况,即需要准备标志来指示“加载”状态。我有一个通用的API,它使用一个模型获取函数和一个可选的初始值。接下来,它有解析、ispend、get和set方法:这允许视图在查询异步模型状态的方式上更加灵活。hasresolve指示该方法是否已经解析,然后next返回一个承诺,该承诺将在当前请求中解析,或者在isPending为false时解析下一个请求。