构建我的backbone.js应用程序

发布于 2024-12-14 04:58:26 字数 2766 浏览 1 评论 0原文

我正在使用 Require.js 创建 Backbone.js 应用程序。每个视图文件对应一个资源(例如“新闻”)。在每个视图文件中,我声明一个主干 每个操作的视图(“索引”、“新”等)。在我收到的视图文件的底部 来自路由器的必要信息,然后决定实例化哪个视图(基于从路由器传入的信息)。

这一切都运行良好,但它需要大量代码,而且似乎不是“backbone.js 方式”。一方面,我依靠 url 来管理状态。另一方面,我没有使用 _.bind,它出现在很多backbone.js 示例中。换句话说,我认为我做得不对,而且我的代码库有味道......关于如何更好地构建我的应用程序有什么想法吗?

router.js

define([
  'jquery',
  'underscore',
  'backbone',
  'views/news'], 
  function($, _, Backbone,  newsView){
    var AppRouter = Backbone.Router.extend({
        routes:{
            'news':'news',
            'news/:action':'news',
            'news/:action/:id':'news'
        },

        news: function(action, id){
            newsView(this, action, id).render();
        }
    });


    var intialize = function(){
        new AppRouter;
        Backbone.history.start()
    };

    return{
        initialize: initialize;
    };
}

news.js ('视图/新闻')

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/news',
  'text!templates/news/index.html',
  'text!templates/news/form.html'

  ], function($, _, Backbone, newsCollection, newsIndexTemplate, newsFormTemplate){

    var indexNewsView = Backbone.View.extend({
        el: $("#content"),

        initialize: function(router){
            ...
        },

        render: function(){
            ...
        }
    });

    var newNewsView = Backbone.View.extend({
        el: $("#modal"),

        render: function(){
            ...
        }
    });

    ...

    /*
     *  SUB ROUTER ACTIONS
     */

    var defaultAction = function(router){
      return new newsIndexView(router);
    }

    var subRouter = {
      undefined: function(router){return defaultAction(router);},

      'index': function(router){ return defaultAction(router);},

      'new': function(){
        return new newNewsView()
      },

      'create': function(router){
        unsavedModel = {
          title : $(".modal-body form input[name=title]").val(),
          body  : $(".modal-body form textarea").val()
        };
        return new createNewsView(router, unsavedModel);
      },

      'edit': function(router, id){
        return new editNewsView(router, id);
      },

      'update': function(router, id){
        unsavedModel = {
          title : $(".modal-body form input[name=title]").val(),
          body  : $(".modal-body form textarea").val()
        };

        return new updateNewsView(router, id, unsavedModel);
      },
    }

    return function(router, action, id){
      var re = /^(index)$|^(edit)$|^(update)$|^(new)$|^(create)$/
      if(action != undefined && !re.test(action)){
        router.navigate('/news',true);
      }
      return subRouter[action](router, id);
    }


  });

I'm in the process of creating a Backbone.js app using Require.js. Each view file corresponds to one resource (e.g. 'News'). Within each view file, I declare a backbone
view for each action ('index', 'new', etc). At the bottom of the view file I receive
the necessary info from the router and then decide which view to instantiate (based on the info passed in from the router).

This all works well, but it requires lots of code and doesn't seem to be the 'backbone.js way'. For one thing, I'm rellying on the url to manage state. For another, I'm not using _.bind which pops up in a lot of backbone.js examples. In other words, I don't think I'm doing it right, and my code base smells... Any thoughts on how to structure my app better?

router.js

define([
  'jquery',
  'underscore',
  'backbone',
  'views/news'], 
  function($, _, Backbone,  newsView){
    var AppRouter = Backbone.Router.extend({
        routes:{
            'news':'news',
            'news/:action':'news',
            'news/:action/:id':'news'
        },

        news: function(action, id){
            newsView(this, action, id).render();
        }
    });


    var intialize = function(){
        new AppRouter;
        Backbone.history.start()
    };

    return{
        initialize: initialize;
    };
}

news.js ('views/news')

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/news',
  'text!templates/news/index.html',
  'text!templates/news/form.html'

  ], function($, _, Backbone, newsCollection, newsIndexTemplate, newsFormTemplate){

    var indexNewsView = Backbone.View.extend({
        el: $("#content"),

        initialize: function(router){
            ...
        },

        render: function(){
            ...
        }
    });

    var newNewsView = Backbone.View.extend({
        el: $("#modal"),

        render: function(){
            ...
        }
    });

    ...

    /*
     *  SUB ROUTER ACTIONS
     */

    var defaultAction = function(router){
      return new newsIndexView(router);
    }

    var subRouter = {
      undefined: function(router){return defaultAction(router);},

      'index': function(router){ return defaultAction(router);},

      'new': function(){
        return new newNewsView()
      },

      'create': function(router){
        unsavedModel = {
          title : $(".modal-body form input[name=title]").val(),
          body  : $(".modal-body form textarea").val()
        };
        return new createNewsView(router, unsavedModel);
      },

      'edit': function(router, id){
        return new editNewsView(router, id);
      },

      'update': function(router, id){
        unsavedModel = {
          title : $(".modal-body form input[name=title]").val(),
          body  : $(".modal-body form textarea").val()
        };

        return new updateNewsView(router, id, unsavedModel);
      },
    }

    return function(router, action, id){
      var re = /^(index)$|^(edit)$|^(update)$|^(new)$|^(create)$/
      if(action != undefined && !re.test(action)){
        router.navigate('/news',true);
      }
      return subRouter[action](router, id);
    }


  });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

从﹋此江山别 2024-12-21 04:58:26

虽然我觉得强调没有真正的“Backbone.js 方式”很重要,但看起来您确实正在复制 Backbone 应该为您做的工作。

我同意为应用程序的每个独立部分配备一个专门的路由器是有意义的。但乍一看,您在“子路由器”部分所做的只是重新创建 Backbone.Router 功能。您的 AppRouter 根本不需要处理 /news URL;您只需使用特定于新闻的路由初始化 NewsRouter 即可,它将处理与新闻相关的 URL:

var NewsRouter = Backbone.Router.extend({
    routes:{
        'news':             'index',
        'news/create':      'create',
        'news/update/:id':  'update',
        'news/edit/:id':    'edit'
    },

    index: function() { ... },

    create: function() { ... },

    // etc
});

只要在调用 Backbone.history.start() 之前对其进行初始化即可code>,它将捕获其路由的 URL 请求,并且您永远不必处理 AppRouter。您也不需要处理视图底部丑陋的代码 - 这基本上只是做核心 Backbone.Router 为您做的事情。

While I feel like it's important to emphasize that there isn't really a "Backbone.js way", it does seem like you're replicating work Backbone should be doing for you.

I agree that it makes sense to have a specialized Router for each independent section of your application. But it looks at first glance like what you're doing in your "sub-router" section is just recreating the Backbone.Router functionality. Your AppRouter doesn't need to deal with /news URLs at all; you can just initialize a NewsRouter with news-specific routes, and it will deal with news-related URLs:

var NewsRouter = Backbone.Router.extend({
    routes:{
        'news':             'index',
        'news/create':      'create',
        'news/update/:id':  'update',
        'news/edit/:id':    'edit'
    },

    index: function() { ... },

    create: function() { ... },

    // etc
});

As long as this is initialized before you call Backbone.history.start(), it will capture URL requests for its routes, and you never have to deal with the AppRouter. You also don't need to deal with the ugly bit of code at the bottom of your view - that's basically just doing what the core Backbone.Router does for you.

回忆追雨的时光 2024-12-21 04:58:26

我也使用 require.js 和backbone,我认为我建议的主要区别是每个文件应该只返回一个视图、模型、路由器或集合。

所以我的主 html 页面需要我的主路由器。该路由器是一个模块,需要一些基于其每条路由的视图和一个引导模型。每个路由器方法将相关的引导模型片段传递给相关的视图。

从那里开始,只要每个文件只是 1 个主干事物(模型、集合、视图、路由器)并且只需要它使用的元素,它就保持非常干净。这会产生大量 js 文件(我当前的项目大约有 100 个),但这就是 require.js 优化发挥作用的地方。

我希望这有帮助。

I'm using require.js and backbone as well I think the main difference that i'd suggest is that each file should return just one view, model, router or collection.

so my main html page requires my main router. That router is a module that requires a few views based on each of it's routes, and a bootstrapped model. Each router method passes the relevant bootstrapped model piece to the relevant view.

From there it stays really clean as long as each file is just 1 backbone thing (model, collection, view, router) and requires just the elements it uses. This makes for a lot of js files (I have about 100 for my current project) but that's where require.js optimization comes into play.

I hope that helps.

灰色世界里的红玫瑰 2024-12-21 04:58:26

为什么不这样构建你的路线:

        routes:{
            'news':'news',
            'news/edit/:id':'editNews',
            'news/new':'newNews',
            ...
        }

Why don't you structure your routes like this:

        routes:{
            'news':'news',
            'news/edit/:id':'editNews',
            'news/new':'newNews',
            ...
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文