如何在backbone.js中设置另一个视图对象

时间:2016-12-17 08:55:17

标签: javascript backbone.js

我的应用程序设计为更改路由器然后呈现其他视图 但是,我不知道创建其他视图对象的通信方式。

router.js

    var app = app || {};
(function() {
    'use strict';
    var views = app.view = app.view || {};
    app.Router = Backbone.Router.extend({
        routes: {
            '*home': 'homeRoute',
            'about': 'aboutRoute',
            'contact': 'contactRoute'
        },
        initialize: function() {
            // create the layout once here
            this.layout = new views.Application({
                el: 'body',
            });
        },
        homeRoute: function() {
            var view = new views.Home();
            this.layout.setContent(view);
        },
        aboutRoute: function() {
            var view = new views.About();
            this.layout.setContent(view);
        },
        contactRoute: function() {
            var view = new views.Contact();
            this.layout.setContent(view);
        }
    });
})();

view.js

var app = app || {};
(function() {
    'use strict';
    //views linitalize
    var views = app.view = app.view || {};
    views.Application = Backbone.View.extend({
        initialize: function() {
            // caching the jQuery object on init
            this.$content = this.$('#content');
            this.$loading = this.$('#loading');
        },
        setContent: function(view) {
            var content = this.content;
            if (content) content.remove();
            this.showSpinner();
            content = this.content = view;
            console.log(view);
            //content rednering
            this.$content.html(content.render().el, this.hideSpinner());
        },
        showSpinner: function() {
          this.$loading.show();
        },
        hideSpinner: function() {
          this.$loading.hide();
        },
    });
    views.Home = Backbone.View.extend({ });
    views.About = Backbone.View.extend({
      initialize: function(){
        this.render();
      },
      render: function(){
        var template =  _.template("<strong>About page</strong>");
      }
    });
    views.Contact = Backbone.View.extend({
      my_template: _.template("<strong>Contact page</strong>");
    });
})();

的index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <ul class="pills">
        <li><a href="#/">Home</a></li>
        <li><a href="#/about">About</a></li>
        <li><a href="#/contact">Contact</a></li>
    </ul>
    <div id="content"></div>
    <div id="loading">load the page...</div>
    <div id="sumMenu"></div>
    <script src="lib/jquery-3.1.1.min.js"></script>
    <script src="lib/underscore.js"></script>
    <script src="lib/backbone.js"></script>
    <script src="lib/backbone.localstorage.js"></script>
    <script src="routers/router.js" ></script>
    <script src="views/view.js" ></script>
    <script src="views/app.js" ></script>
  </body>
</html>

如果您查看此代码,您就会明白。我很难沟通上面所说的内容。

查看 view.js ,我写了3个视图属性(homeaboutcontact),其中包含的代码不是&#39;跑。

my_template: _.template("<strong>Contact page</strong>");

我真的想知道对象创建后,如何设置对象值和渲染?

1 个答案:

答案 0 :(得分:2)

代码受my other answer的启发,但您需要阅读Backbone documentation(以及Underscore's)以了解正在发生的事情,你是什么正在做什么以及需要做些什么来为它添加功能。否则,你总是会从工作代码中分离出一些你不理解的新东西。

Backbone doc简短而且甜蜜,source code充满了评论。不要阅读所有Underscore的文档,但至少阅读您正在使用的函数的文档(如_.template)。

Router routes

由于您在没有先检查其是否有效的情况下从我的其他答案中复制粘贴了确切的代码,因此您复制了我犯的错误。 应首先定义更具体的路线,并使用全能路线

routes: {
    'about': 'aboutRoute',
    'contact': 'contactRoute',
    // put the catch-all last
    '*home': 'homeRoute',
},

实例化新路由器时,其构造函数调用_bindRoutes来解析从最后一个到第一个路由的路由。

_bindRoutes: function() {
  if (!this.routes) return;
  this.routes = _.result(this, 'routes');
  var route, routes = _.keys(this.routes);
  while ((route = routes.pop()) != null) {
    this.route(route, this.routes[route]);
  }
},
     

稍后添加的路线可能会覆盖先前声明的路线。

render function

您认为以下内容会怎样?

render: function(){
    var template =  _.template("<strong>About page</strong>");
}

所以现在所做的就是:

  • 它创建了一个新功能,
  • 将其放在名为template
  • 的局部变量中
  • 并且什么都不做。

甚至是这样:

my_template: _.template("<strong>Contact page</strong>");
视图上的

my_template属性不是标准的Backbone,所以如果你不对它做任何事情,它本身就不会做任何事情。

要理解,您需要知道 Underscore _.template函数将模板字符串作为参数(以及可选的设置对象),返回新的预编译模板函数将对象作为参数。More info and examples

Backbone视图的render函数留给开发人员覆盖。它理想情况下应该呈现一些东西并且是idempotent

一个简单的观点可能是:

views.About = Backbone.View.extend({
    template: _.template("<strong>About page</strong>"),
    render: function() {
        this.$el.html(this.template());
        return this;
    }
});
  

一个好的约定是在return this末尾的render启用   链式电话。

你应该这样做,因为你在代码中链接了调用:

content.render().el

jQuery和el

为什么通过this.hideSpinner()

this.$content.html(content.render().el, this.hideSpinner());

虽然它确实使用视图#content更改el div的HTML,但使用this.hideSpinner()返回的值作为第二个参数毫无意义。

jQuery's .html function只需要一个参数。

放置加载微调器的位置?

不在同步DOM操作中。在删除之前放置一个微调器是没用的。

当存在某种异步加载时,加载微调器是有意义的,并且您希望通知用户该页面没有崩溃或冻结。

假设您要为主页加载新闻。

homeRoute: function() {
    console.log("showing the spinner");
    this.layout.showSpinner();

    var collection = new Backbone.Collection({
            url: "/you/api/url/for/latest/news" // simple example
        }),
        view = new views.Home({
            collection: collection
        });

    collection.fetch({
        context: this,
        success: function() {
            console.log("removing the spinner");
            this.layout.hideSpinner();
            this.layout.setContent(view);
        }
    });

    console.log("End of homeRoute function");
},

在控制台中,您将按以下顺序查看日志:

showing the spinner
End of homeRoute function
removing the spinner

更多信息,请参阅: