11

我在一个项目中使用 Mithril JS,但我无法准确理解如何挂钩到 Ajax 生命周期。就像我有一个 Ajax 请求需要一段时间,我想显示一个微调器。非常基本,但我似乎无法弄清楚这是怎么发生的。

我想为微调器使用与 Ajax 请求正在寻找的内容相同的容器。

这是我的设置:

var Thing = function (data) {
  var p = m.prop;
  this.title = p(data.title);
  this.timestamp = p(moment.unix(data.timestamp));
}

Thing.list = function(options) {
  m.request({method: "GET", url: "/things.json", type: Thing, background: true});
};

MyApp.components.thingsList = {
  controller: function ThingListController() {
    this.things = m.prop([]);
    Thing.list().then(this.things).then(m.redraw);
  },

  view: function thingListView(ctrl) {
    return m('div#thing-tab', [
      m('ul#things', [
        ctrl.things().map(thingView)
      ])
    ]);
  }
};

function thingView(thing) {
  ...some view stuff...
}

我已经让它按照我想要的方式工作,但我只是不知道如何挂钩到 ajax 生命周期。同样,我只想在请求开始时显示一个微调器,然后用 ajax 请求的结果替换它。

非常感谢任何和所有帮助!

谢谢,

4

2 回答 2

11

一种方法是包装m.request在另一个函数中,该函数返回完成状态(基于您通过 m.request 承诺链设置的标志)和数据,然后使用该background: true选项来防止重绘延迟,以及绑定m.redraw到承诺链,以便在请求之后发生重绘。

这最初是在这里描述的:https ://github.com/lhorie/mithril.js/issues/192

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) {
      m.redraw()
      return value
    }),
    ready: completed
  }
}

var MyController = function() {
  this.things = requestWithFeedback({method: "GET", url: "/things"})
}
var myView = function(ctrl) {
  return !ctrl.things.ready() ? m("img[src=loading.gif]") : m("ul", [
    ctrl.things.data().map(function(thing) {
      return m("li", thing.name)
    })
  ]) 
}

m.module(document.body, {controller: MyController, view: myView})
于 2014-08-18T21:30:29.267 回答
3

我发现我认为是一种优雅的方式来做到这一点,基于 Mithril 在模型更新时重新渲染整个 UI(有差异)的原则。以下示例用于保存内联更新。

当我有通过 AJAX 更改的模型的某些部分时,我在模型中设置了一个临时标志(如果你想将它分开,你可以在视图状态模型中轻松地做到这一点),完成后,我只是删除标志并调用 m.redraw():

function updateRecord(ctl,evt,row,idx,rcd) {
    rcd._action="save";
    apiSender({ method: "PATCH", url: apiUrl, data: dropFlags(rcd) }).then(done,fail).then(null,logObject);

    function done(rspdta) {
        delete rcd._action;
        m.redraw();
        };

    function fail(rspdta) {
        ajaxError(ctl,rspdta,"Update customer "+rcd.CustomerId+" ("+rcd.ContactName+")");
        rcd._action="edit";
        m.redraw();
        };
    }

在从模型数据重建的视图中,我以标志为条件:

if     (rcd._action=="edit"   ) { con=crtListRecordView_Edit   (rcd,idx             ); }
else if(rcd._action=="save"   ) { con=crtListRecordView_Waiting(rcd,idx,"Saving"    ); }
else if(rcd._action=="delete" ) { con=crtListRecordView_Waiting(rcd,idx,"Deleting"  ); }
else if(rcd._action=="merge"  ) { con=crtListRecordView_Waiting(rcd,idx,"Merging"   ); }
else if(rcd._action=="refresh") { con=crtListRecordView_Waiting(rcd,idx,"Refreshing"); }
else                            { con=crtListRecordView_Normal (rcd,idx             ); }
return m("tr", con);

这允许对不同记录进行多个并发操作,并向用户提供精美、清晰和不显眼的反馈。

这是它的样子:

普通的:

普通的

编辑:

编辑

保存:

保存

于 2014-09-26T15:28:51.873 回答