路由器是否应该负责网络请求?(骨干.js)

Should the Router be responsible for network requests? (Backbone.js)

本文关键字:骨干 js 请求 网络 是否 路由器      更新时间:2023-09-26

我与一位同事就路由器的责任存在分歧。在我们的单页应用程序中,我的印象是通过触发的事件(即 Backbone.Events(处理网络请求 (AJAX(,如下所示:

events : {
    'click a#getUsers' : 'updateModels'
}
updateModels: function() {
    $.ajax(); or this.Model.fetch();
}

然而,他的理解是,网络请求应该在URL更改时通过路由器处理(取决于单击,该单击更改了URL,如下所示a[href="#getThings"]

var App = Backbone.Router.extend({
    routes: {
        "" : "main",
        "thing" : "getThings"
    }
    getThings: function() {
        this.newView = new NewView();
        $.ajax(); // which populates the view with data
    }
});

我想知道执行网络请求的主干原因是什么。

绝大多数 AJAX 请求应以主干modelcollection开头,并通过 backbone.sync 函数进行处理。关键方法是model.fetch()collection.fetch()model.save()

Backbone 非常灵活,只处理一组非常原始的用例,因此在某些情况下,您需要跳出这些边界,但任何对视图或路由器中$.ajax的调用都是 MVC 失败的强烈代码气味。

解决您的一些细节。

视图是否可以调用model.fetch()来加载数据?

是的,这是完全好的和惯用的骨干。

视图是否可以发出最终将加载数据的事件?

是的,这完全没问题。这仅在应用程序复杂性增加时调用model.fetch()之外是必要的,并且事件发出允许的解耦是有价值和保证的。对于待办事项列表,这通常是矫枉过正。对于大型应用程序,这可能是一种干净的方法。

每个模型提取是否都会导致浏览器 URL 发生变化?

不。事实上,许多单页应用程序只是永远存在于"/"处。路由到唯一 URL 是可选的。有些应用程序很容易适应它,而另一些则不那么适合。不要将"应用程序需要数据 X"等同于"浏览器 URL 需要为 X"。这些是正交的。如果用户在总统列表中单击"比尔克林顿"的视图,并且您想将URL更改为"/Presidents/clinton",那么请继续并触发一条新路由,这是完全有意义的,但有时您只需要一些数据而不更改URL。

总结路由器的职责,我认为如下:

  • 根据 URL,应该显示哪个视图?
  • 同样基于 URL,是否有需要提取模型 ID 并将其实例化到模型实例中?
  • 连接内容并呈现视图

因此,典型的路由器方法伪代码可能是:

  • 当 URL 与/Presidents/:name 匹配时,响应如下
  • 获取 :name 参数并制作总统模型
  • 实例化 PresidentView,并向其传递模型
  • 调用 PresidentView.render(( 并将视图的元素交换到 DOM 中整个页面布局中的适当位置
使用Backbone,

你应该让Backbone为你完成大部分的ajax请求,这些请求通常是从你的视图触发的,而不是从路由器触发的。而且我永远不会使用 jQuery ajax 请求,而你可以使用 Backbone 请求。 this.model.fetch()是获取模型的正确方法。我认为路由器是定位页面的一种方式,但更精细的细节应该留给视图。但是,在路由器中的逻辑与视图/集合/模型中的逻辑之间进行选择与其说是科学,不如说是艺术,我会查看其他 Backbone 示例以获得更多指导。我认为,在很多情况下,网络请求是在视图中处理的,因为它更容易。

为了回应您在下面的评论,每当从服务器返回数据时,Backbone 都会使用 parse 来获取所需的信息,因此重写 fetch 将是一个糟糕的决定。您可以覆盖模型的 parse 方法以获取所需的信息,仅此而已。即:

var YourModel = Backbone.Model.extend({
    parse: function(response) {
        //You can manipulate the object in other ways as well, 
        //but here's how you'd delete info
        delete response.junk;
        return response;
    }
});

类似地,每次你执行this.model.save()时,它在模型发送到服务器之前都使用 toJSON((,你也可以覆盖它:

toJSON: function() {
    // default -> return _.clone(this.attributes);
    return _new code here_;
}