如何将视图/模型的引用传递给backbone.js中的其他视图/模型/路由

时间:2016-11-03 02:56:08

标签: javascript backbone.js

所以我对backbone.js真的很陌生,我想要了解基本概念,以获取零件(视图/模型/路线)与其他部分进行交互。

这是一个例子。我有一个'screen'模型对象,由'singleScreen'视图呈现给页面。我还有一个'侧边栏'模型和正在渲染的视图。当我点击侧边栏中的链接时,我想让它渲染一个不同的屏幕模型对象,并根据我给出我的屏幕模型的'name'属性在单独的html div(标题)中更改一些HTML。

所以第一个问题,是否应该在routes.js文件中完成重新呈现不同视图和更改标题html的所有代码?看起来这个文件会非常快。如果是这样,我如何得到我想在routes.js文件中呈现的模型对象的引用,以便我可以访问myModel.name(在app.js文件中实例化)等内容?

我是否将浏览器历史记录和我的视图呈现为单独的内容,并在我的app.js文件(我实例化所有对象的文件)中添加“链接被点击,呈现此”功能的代码?如果是这样的话,如果用户试图通过输入URL直接转到视图而不是点击?我的应用程序如何知道要渲染的内容?

或者,就我所知,这是最可能出现的情况,

我是否使用模型/视图的初始化函数来触发/监听单击链接时的事件(或者更改了backbone.history()?)并调用渲染?

我已经搞乱了所有3种方法,但无法理解如何将对象的引用传递给应用程序的其他部分,而不仅仅是将这些对象作为全局变量(这感觉非常错误)。

对于最后一个场景,我搞砸了各种事件,但我读过的每个地方都说你必须包含对它正在监听的对象的引用,这似乎打败了设置事件对象和监听的整个目的。一个事件,而不仅仅是查询该对象变量的状态......

例如。

this.listenTo(sidebarModel , "change:selected", this.render());

如何将对sidebarModel对象的引用传递给singleScreen视图,以便知道它应该被监听的内容。

我并不是真的在寻找一个编码的答案,更多的只是对最佳实践的理解以及如何完成事情。我觉得我很接近,但我知道我缺少/不理解的东西这就是为什么我自己无法弄明白这一点,所以对整个主题的一点点启发将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

首先,您需要了解每个Backbone类的作用。首先阅读MVC可能有所帮助。

模型

渲染视图时,模型不是必需的。它的作用是处理数据,可以是本地数据,也可以是API。影响数据的所有函数都应该在模型中,并且模型不应该具有与渲染相关的任何内容。

总会有异常,您可以使用模型处理仅与渲染相关的数据,但是当您发现此类情况时,您就会知道。

一个简单的例子就是一本书:

// The Book model class
var Book = Backbone.Model.extend({ 
    idAttribute: 'code',
    urlRoot: '/api/book'
});

// a Book instance
var solaris = new Book({ code: "1083-lem-solaris" });

从API中获取将调用:

// GET http://example.com/api/book/1083-lem-solaris
solaris.fetch(); // this is async

获取时,API返回JSON编码数据。

{
    "code": "1083-lem-solaris",
    "title": "Test title",
}

属性与现有属性合并,添加尚未存在的属性,并覆盖已存在的属性的值。

集合

集合的作用是管理一组模型,这些模型同样可以是本地的,也可以从API中获取。它应该只包含与管理集合相关的功能。

var Library = Backbone.Collection.extend({
  model: Book,
  url: '/api/book'
});

var myLibrary = new Library();

// just adds an existing book to our array
myLibrary.add(solaris);

您可以获取一个集合以从API中获取现有图书数组:

myLibrary.fetch();

API应返回:

[
    { "code": "blah-code-123", "title": "Test title" }, 
    { "code": "other-code-321", "title": "Other book title" } 
]

使用该集合创建新书并与API同步:

var myNewBook = myLibrary.create({ title: "my new book" });

这将发送带有属性的POST请求,API应返回:

{ "code": "new-code-123", "title": "my new book" }, 

查看

视图处理其根DOM元素。它应该处理来自DOM的事件。它最适合用于包装小型组件并从较小的组件构建更大的组件。

将链接直接放在模板中,锚标记的href中。没有必要使用事件。

<a href="#my-route">link</a>`

这是我如何渲染(简化)列表。

// book list item
var BookView = Backbone.View.extend({
    tagName: 'li',
    template: _.template('<a href="#book/<%= code %>"><%= title %></a>'),
    initialize: function() {
        // when the model is removed from the collection, remove the view.
        this.listenTo(this.model, 'remove', this.remove);
    },
    render: function() {
        this.$el.empty().append(this.template(this.model.toJSON()));
        return this;
    }
});

// book list
var LibraryView = Backbone.View.extend({
    template: '<button type="button" class="lib-button">button</button><ul class="list"></ul>',
    events: {
        'click .lib-button': 'onLibButtonClick'
    },

    initialize: function(options) {

        this.listenTo(this.collection, 'add', this.renderBook);
    },

    render: function() {
        // this is a little more optimised than 'html()'
        this.$el.empty().append(this.template);

        // caching the list ul jQuery object
        this.$list = this.$('.list');

        this.collection.each(this.renderBook, this);

        return this; // Chaining view calls, good convention http://backbonejs.org/#View-render
    },

    addItem: function(model) {
        // Passing the model to the Book view
        var view = new BookView({
            model: model
        });
        this.$list.append(view.render().el);
    },

    onLibButtonClick: function() {
        // whatever
    }

});

路由器

路由器处理路由并且应该尽可能简单,以避免它变得太快太快。它可以获取集合和模型,或者视图可以处理它,这是模式的问题。

var LibraryRouter = Backbone.Router.extend({
    routes: {
        '*index': 'index',
        'book/:code': 'bookRoute',
    },

    index: function() {
        var library = new LibraryView({
            el: 'body',
            // hard-coded collection as a simple example
            collection: new Library([
                { "code": "blah-code-123", "title": "Test title" }, 
                { "code": "other-code-321", "title": "Other book title" } 
            ])
        });
        library.render();
    },
    bookRoute: function(code) {
        var model = new Book({ code: code });
        // here, I assume an API is available and I fetch the data
        model.fetch({
            success: function() {
                var view = new BookPageView({
                    el: 'body',
                    model: model
                });
                view.render();
            }
        });
    }
});

活动

Backbone中的所有东西都有Events mixin,甚至是全局Backbone对象。因此,每个类都可以使用listenTo将回调绑定到事件。

对Backbone中的所有内容进行深入研究将非常漫长,所以请提出问题,我会尝试扩展我的答案。