繁体   English   中英

如何在骨干.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个views属性( homeaboutcontact )和那些包含无法运行的代码。

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

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

该代码的灵感很大程度上来自于我的其他答案 ,但是您需要阅读Backbone文档 (以及Underscore的 文档 )以了解正在发生的事情 ,正在做什么以及需要做什么才能为其添加功能。 否则,您将始终从工作代码中移入一个您不理解的新混乱中。

Backbone文档简短而优美, 源代码中充满了注释。 不要阅读Underscore的所有文档,但至少请阅读您正在使用的功能的文档(例如_.template )。


路由器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功能

您认为以下内容会做什么?

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

因此,现在要做的就是:

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

甚至这个:

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

my_template上的my_template属性不是标准的Backbone,因此,如果您不对其进行任何操作,则它本身不会做任何事情。

要理解,您需要知道_.template函数将模板字符串作为参数(以及可选的设置对象),并返回一个新的预编译模板函数 ,该函数将对象作为参数。 更多信息和示例

骨干视图的render功能留给开发人员覆盖。 理想情况下,它应该呈现出东西并且是幂等的

一个简单的视图可能是:

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

一个好的约定是在render结束时return this以启用链接调用。

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

content.render().el

jQuery和el

你为什么要传递this.hideSpinner()

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

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

jQuery的.html函数仅采用一个参数。


在哪里放置装载微调器?

不在同步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

有关更多信息,请参见:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM