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

how to set the another view objects in 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个浏览量属性(home,about,contact) 和那些包含不 运行.

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

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

该代码深受 , but you need to read the Backbone documentation (and also Underscore's) 的启发,以了解正在发生的事情、您正在做什么以及需要做什么才能为其添加功能。否则,您总是会偏离工作代码,陷入您不理解的新混乱中。

Backbone 文档短小精悍,source code is filled with comments. Don't read all of Underscore's doc, but read at the least the documentation for the functions you're using (like _.template).


Router routes

由于您没有先检查它是否有效就从我的另一个答案中复制粘贴了确切的代码,因此您复制了我犯的一个错误。 应首先定义更具体的路由,最后定义通用路由

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

当实例化一个新的 Router 时,它的构造函数调用 _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]);
  }
},

Routes added later may override previously declared routes.


render function

你认为下面会做什么?

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

那么现在要做的就是:

  • 它创建了一个新函数,
  • 将其放入名为 template
  • 的局部变量中
  • 什么都不做。

甚至这样:

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

my_template 属性 视图不标准 Backbone,所以如果你什么都不做,它自己不会做任何事。

要理解,您需要知道 Underscore _.template 函数将模板字符串作为参数(以及可选的设置对象)和 returns一个新的预编译模板函数,它将一个对象作为参数。 ()

Backbone 视图的 render 函数留给开发人员覆盖。它应该理想地渲染一些东西并且是 idempotent.

一个简单的视图可以是:

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

A good convention is to return this at the end of render to enable chained calls.

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

content.render().el

jQuery 和 el

你为什么通过this.hideSpinner()

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

虽然它确实将 #content div 的 HTML 更改为视图的 el,但使用 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

更多信息,请参阅:

  • JavaScript inheritance, Making copy of objects and Chaining