我如何将对视图/模型的引用传递给骨架.js中的其他视图/模型/路由 [英] How do I pass references of views/models to other views/models/routes in backbone.js

查看:134
本文介绍了我如何将对视图/模型的引用传递给骨架.js中的其他视图/模型/路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我真的是belish.js的新手,我试图了解有关使零件(视图/模型/路线)与其他零件进行交互的基本概念.

So I'm really new to backbone.js and I'm trying to understand the basic concept when it comes to getting parts(views/models/routes) to interact with other parts.

这是一个例子.我有一个屏幕"模型对象,由单屏"视图呈现到页面.我也有一个侧边栏"模型和正在渲染的视图.当我单击侧边栏中的链接时,我希望它呈现一个不同的屏幕模型对象,并根据我给我的屏幕模型提供的名称"属性,在单独的html div(标题)中更改一些HTML.

Here's an example. I have a 'screen' model object being rendered by a 'singleScreen' View to the page. I also have a 'sidebar' model and view being rendered. When i click on a link in the sidebar i want it to render a different screen model object and alter some of the HTML in a separate html div (the heading) according to the 'name' attribute i gave my screen model.

因此,第一个问题是,用于重新渲染不同视图并更改标题html的所有代码都应在route.js文件中完成吗?似乎该文件很快就会变得很大.如果是这样,我如何获得要在route.js文件中呈现的模型对象的引用,以便可以访问myModel.name之类的东西(在app.js文件中实例化)?

So first question, should all of the code for re-rendering a different view and changing the heading html be done in the routes.js file? It seems like that file would get pretty big pretty fast. If so how do i get a reference to the model object i want to render in the routes.js file so i can access things like myModel.name (which is instantiated in the app.js file)?

我是否将浏览器的历史记录和视图的呈现方式分开处理,并在app.js文件(实例化所有对象的文件)中添加单击链接,呈现此功能"的代码?如果是这种情况,如果用户尝试通过键入URL而不是单击直接进入视图,我的应用程序如何知道要呈现的内容?

Do I handle the browser history and rendering of my view as separate things and add code for 'link is clicked, render this' functionality in my app.js file (the file where I instantiate all my objects)? If that's the case how does my app know what to render if a user tries to go directly to a view by typing in the URL, rather than clicking?

或,据我所知,这是最有可能的情况,

OR, and this is the most likely scenario as far as i can tell,

我是否使用模型/视图的初始化功能来触发/侦听单击链接(或更改ribs.history()时)的事件并调用渲染?

Do i use the initialize functions of my models/views to trigger/listenTo an event for when a link is clicked(or backbone.history() is changed?) and call render?

我搞砸了所有3种方法,但是不了解如何将对象的引用传递给应用程序的其他部分,而不仅仅是使这些对象成为全局变量(感觉很不对劲).

I've messed around with all 3 approaches but couldn't understand how to pass references of objects to other parts of the app, without just making those objects global variables (which feels so wrong).

在最后一个场景中,我弄乱了事件,但是我读过的每个地方都说您也必须包含对其正在监听的对象的引用,这似乎违反了设置事件对象和监听对象的全部目的.一个事件,而不仅仅是查询该对象的变量状态...

For the last scenario, I messed around with events but everywhere I've read says you have to include a reference to the object that it's listening too, which seems to defeat the whole purpose of setting up an events object and listening for an event rather than just querying the state of a variable of that object...

例如

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

我如何将对sidebarModel对象的引用传递给singleScreen视图,以使其了解要听的内容.

How do i pass a reference to sidebarModel object to the singleScreen view for it to know what it's meant to be listening to.

我并不是真正在寻找编码答案,更多的是了解最佳实践以及应该如何做.我感觉自己已经接近了,但我知道我缺少/不了解那些这就是为什么我自己无法弄清楚这一点,因此对整个主题的一点启发将是不胜感激的.谢谢.

I'm not really looking for a coded answer, more so just an understanding of best practices and how things are meant to be done.I feel like I'm close but I know i'm missing/not understanding something which is why I'm not able to figure this out myself, so a little enlightening on the whole topic would be greatly appreciated. Thanks.

推荐答案

首先,您需要了解每个Backbone类的角色.首先阅读 MVC 可能会有所帮助.

First, you need to understand the role of each Backbone classes. Reading on MVC first might help.

渲染视图时不需要模型.它的作用是处理可以是本地数据或来自API的数据.所有影响数据的功能都应该在模型中,并且模型不应该具有与渲染相关的任何内容.

The model isn't necessary when rendering a view. Its role is to handle the data, which can be local, or from an API. All the functions that affect the data should be in the model, and a model shouldn't have anything related to rendering.

总是有例外,您可以使用模型来处理仅与渲染相关的数据,但是发现这种情况时您会知道的.

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

A simple example is a book:

// 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编码的数据.

When fetching, the API returns the JSON encoded data.

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

将这些属性与现有属性合并,添加尚未存在的属性,并覆盖已经存在的属性的值.

The attributes are merged with the existing attributes, adding the ones that are not there yet, and overwriting the values of the ones already there.

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

A collection's role is to manage an array of models, which, again, can be local or fetched from an API. It should contain only functions related to managing the collection.

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获取一系列现有书籍:

You can fetch a collection to get an array of existing books from an API:

myLibrary.fetch();

API应该返回:

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

使用收藏集创建一本新书并与API同步:

Using the collection to create a new book and sync with the API:

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

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

This will send a POST request with the attributes and the API should return:

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

查看

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

View

The view handles its root DOM element. It should handle events from its DOM. It's best used to wrap small component and build bigger components from smaller components.

直接在链接的锚标签href中的模板中放置链接.无需为此使用事件.

Put links directly in the templates, in the href of an anchor tag. There's no need to use events for that.

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

这是我呈现(简化)列表的方式.

Here's how I render (simplified) a list.

// 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
    }

});

路由器

路由器处理路由,并且应尽可能简单,以免其过大或过快.它可以获取集合和模型,或者视图可以处理,这只是模式问题.

Router

The router handle routes and should be as simple as possible to avoid it getting too big too fast. It can fetch collections and models, or the view can handle that, it's a matter of pattern at that point.

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 混合,甚至是全局Backbone对象.因此,每个类都可以使用listenTo将回调绑定到事件.

Events

Everything in Backbone has the Events mixin, even the global Backbone object. So every class can use listenTo to bind callbacks to events.

深入了解Backbone中的所有内容很长,因此提出问题,我将尝试扩展答案.

It would be very long to go in depth for everything in Backbone, so ask questions and I'll try to extend my answer.

这篇关于我如何将对视图/模型的引用传递给骨架.js中的其他视图/模型/路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆