如何重用视图?

发布于 2024-12-19 00:20:02 字数 118 浏览 0 评论 0原文

如何创建“部分”并在整个 Backbone 应用程序中重复使用它们?例如,我应该遵循什么 Backbone 约定/方法才能创建导航栏“视图”并在应用程序的所有视图中重复使用它?本质上,我希望复制 Rails 的布局和部分。

How can I create "partials" and re-use them throughout my Backbone application? For example, what Backbone convention/methodology should I follow that will allow me to create a navigation bar "view" and re-use it in all my views in my application? Essentially, I'm looking to replicate Rails' layouts and partials.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

世态炎凉 2024-12-26 00:20:02

我此时此刻使用它的方式
在您的具体情况下,给定的导航栏,

我什至没有应用程序视图,我有我的页面,其中包含某些默认的 html。
它包含一些视图占位符,主要内容,搜索视图,
如前所述,导航栏视图。我不必在其他视图中重复使用导航视图
因为它不在我的页面视图内。因此,当我更改页面时,导航保持不变,

它会侦听从路由器调用的某些事件,并且它将根据该事件的参数更改导航视图的状态。

但是,如果您确实想使用视图并重用它们
看看 Tim Branyen 正在开发的布局管理器 https://github.com/tbranyen/backbone.layoutmanager ,它是一个主干插件,可以完成您要求的许多事情。

我以前没有使用过它,除了在一个小型测试应用程序中,但它看起来很有希望。

根据要求编辑

,这里是一些示例代码,正如我解释的那样,我如何使用导航在此应用程序中工作,
它可能不是最先进的演示,但它只是一个如何在一个视图中更改另一个视图中的某些内容的想法。

我在代码中定义了一个事件聚合器:

    var eventAggregator = _.extend({}, Backbone.Events);

我有一个导航视图:

    Navigation.Views.Nav = Backbone.View.extend({

        initialize: function () {
            eventAggregator.bind("navigation:route", this.highlight);
        },

        highlight: function (arg) {
            $('.active', this.el).removeClass('active');
            $('li', this.el)
                .filter(function () {
                    return $(this).data('nav') == arg;
                })
                .addClass('active');
        }

    })

// for the size of the code, i removed many elements, and only left the most important parts,
// as you can see, the navigation view, binds to my event event aggregator object, to listen to any 'navigation:route' event.

当然我有一个加载其他视图的路由器:

    Movies.Router = Backbone.Router.extend({

        views: {},

        initialize: function () {
            this.showView = App.showView;
            this.views.Edit = new Movies.Views.Edit({});
            this.views.List = new Movies.Views.List({ collection: Movies.List });
            this.views.Detail = new Movies.Views.Detail({});
        },

        routes: {
            "movies": "loadMovies",
            "movies/add": "addMovie",
            "movie/:slug": "loadMovie",
            "movie/:slug/edit": "editMovie"
        },

        // show the list of all movies.
        loadMovies: function () {
            this.showView(this.views.List);
            eventAggregator.trigger('navigation:route', 'movies');
        },

        // find the movie with the given slug, and render it to the screen.
        loadMovie: function (slug) {
            this.views.Detail.model = Movies.List.detect(function (movie) {
                return movie.get('Slug') === slug;
            });
            this.showView(this.views.Detail);
            eventAggregator.trigger('navigation:route', 'movies');
        },

        // find the movie with the given slug, and render it's edit template to the screen.
        editMovie: function (slug) {
            this.views.Edit = Movies.List.detect(function (movie) {
                return movie.get('Slug') === slug;
            });

            this.showView(this.views.Edit);
            eventAggregator.trigger('navigation:route', 'movies');
        }
    });

// most important part here is, you see how every routing function, has the  eventAggregator.trigger('navigation:route', 'movies'); which basically triggers the event (on the eventAggregator, the above listed view, binds to that event and when it comes in it calls a function, in my case this just sets an active class on the menu item.

所以,虽然我在技术上没有从另一个视图调用 1 个视图,但它的原理是相同的,
您可以从任何地方的 eventAggregator 对象上引发事件,并侦听这些事件并对其采取行动。

the way i've been using it at this very moment,
in your specific situation, the given navigation bar,

i don't even have an app view, i got my page, with certain default html in it.
and it holds a few placeholders for views, the main content, the search view,
and as said, a navigation bar view. i don't have to re-use a navigation view in other views
since it is not inside my page's view. so when i change the page, the navigation stays

it listens to certain events called from the router, and it will change the state of my navigation view depending on that event's arguments.

if you however really want to work with views and re-use them
take a look into the layout manager being developed by Tim Branyen https://github.com/tbranyen/backbone.layoutmanager, it is a backbone plugin that does many of the things you are asking.

i have not used it before, except in a small test application, but it looks promissing.

edit

as requested, here is some example code, as i explained how i work in this app with my navigation,
it might not be the most advanced demo, but it is just an idea how to change something in 1 view from another.

i have an event aggregator defined in my code:

    var eventAggregator = _.extend({}, Backbone.Events);

i have a navigation view:

    Navigation.Views.Nav = Backbone.View.extend({

        initialize: function () {
            eventAggregator.bind("navigation:route", this.highlight);
        },

        highlight: function (arg) {
            $('.active', this.el).removeClass('active');
            $('li', this.el)
                .filter(function () {
                    return $(this).data('nav') == arg;
                })
                .addClass('active');
        }

    })

// for the size of the code, i removed many elements, and only left the most important parts,
// as you can see, the navigation view, binds to my event event aggregator object, to listen to any 'navigation:route' event.

and of course i have a Router that loads other views:

    Movies.Router = Backbone.Router.extend({

        views: {},

        initialize: function () {
            this.showView = App.showView;
            this.views.Edit = new Movies.Views.Edit({});
            this.views.List = new Movies.Views.List({ collection: Movies.List });
            this.views.Detail = new Movies.Views.Detail({});
        },

        routes: {
            "movies": "loadMovies",
            "movies/add": "addMovie",
            "movie/:slug": "loadMovie",
            "movie/:slug/edit": "editMovie"
        },

        // show the list of all movies.
        loadMovies: function () {
            this.showView(this.views.List);
            eventAggregator.trigger('navigation:route', 'movies');
        },

        // find the movie with the given slug, and render it to the screen.
        loadMovie: function (slug) {
            this.views.Detail.model = Movies.List.detect(function (movie) {
                return movie.get('Slug') === slug;
            });
            this.showView(this.views.Detail);
            eventAggregator.trigger('navigation:route', 'movies');
        },

        // find the movie with the given slug, and render it's edit template to the screen.
        editMovie: function (slug) {
            this.views.Edit = Movies.List.detect(function (movie) {
                return movie.get('Slug') === slug;
            });

            this.showView(this.views.Edit);
            eventAggregator.trigger('navigation:route', 'movies');
        }
    });

// most important part here is, you see how every routing function, has the  eventAggregator.trigger('navigation:route', 'movies'); which basically triggers the event (on the eventAggregator, the above listed view, binds to that event and when it comes in it calls a function, in my case this just sets an active class on the menu item.

so, while i'm not technically calling 1 view from another, it is the same principle,
you can raise events from anywhere, on an eventAggregator object, and listen to those events and act upon them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文