如何使用m的值。使用背景时使用MithrilJS中的请求:true?

时间:2021-07-01 07:15:49

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.requests 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.requests 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时解析下一个请求。