【问题标题】:DomReady with backbone.js带有主干.js 的 DomReady
【发布时间】:2012-10-26 23:40:07
【问题描述】:

我正在使用backbone.js 创建一个单页应用程序。我是主干新手,所以请原谅任何错误的语义。

我的问题是渲染视图时。

最初,我的 index.html 中有一个执行某些 dom 操作(图像滑块)的 javascript。

JS 包含在 $(window).load() 中,所以启动时一切正常。 除非从 url 加载页面,否则代码显然不会执行。代码不会从主干视图或路由器运行。所以页面在没有 dom 操作的情况下加载。

我尝试将我的代码插入到视图中的渲染和初始化函数中,但无济于事。我应该将此代码添加到路由器吗?这似乎有点骇人听闻。

我应该在哪里包含“dom ready”代码? 和/或是否有更好的方法来管理主干中加载的视图及其 dom 元素?

代码:

home.js

window.HomeView = Backbone.View.extend({
initialize:function () {
    this.render();
},

render:function () {
    $(this.el).html(this.template());

    this.startOrbits();
    return this;
},



startOrbits:function(){
    $(window).load(function() {
        $('#orbit-main').orbit({ fluid: '16x6', swipe:true });
        $('#orbit-news').orbit({ fluid: '8x6', bullets: true, directionalNav:false, captions:true, advanceSpeed: 9000});
    });
},




});

【问题讨论】:

  • 您不应该能够在适当的render 方法中使用this.$('#orbit-main').orbit(...) 吗?只需将 #orbit-main 放在 this.$el 之后即可。
  • @mu 太短:我在渲染函数中添加了 this.startOrbits,我也尝试在渲染()之后添加内部初始化; .代码在新视图仍然呈现之前运行。
  • 仔细阅读我的评论:$(x)this.$(x) 是不同的东西。 $(x) 仅在 x 在 DOM 中时有效,this.$(x)xthis.el 中时有效,即使 this.el 尚未添加到 DOM 中。
  • 我不知道我能做到这一点。感谢您指出了这一点。不幸的是,这不起作用,我收到一个错误,说轨道不是函数。我确实在下面找到了解决方案。感谢您的意见。

标签: backbone.js backbone-views domready


【解决方案1】:

我找到了解决方案。 在我的路由器函数中注释掉 if 语句后,事情进展顺利。

 home: function () {
            // if (!this.homeView) {
                this.homeView = new HomeView();
            // }
            $('#main-content').html(this.homeView.el);
            this.homeView.startOrbits();
            this.headerView.selectMenuItem('home');
        },

我确实意识到这意味着我会在每个溃败触发器上创建一个新视图。 请随时提供更优化的解决方案。

【讨论】:

    【解决方案2】:

    但是当我转到另一个视图,然后返回时,代码显然没有 兴奋

    我不太确定这意味着什么。撇开“兴奋”的部分不谈,你不会“去”观点;视图只是向页面添加元素或向现有元素添加逻辑的方法。

    如果我不得不猜测,我会想象您正在使用 Backbone 路由器在虚拟“页面”之间移动(并且您使用视图来制作这些页面)。如果是这种情况,您需要查看 Backbone 路由器事件:

    http://documentcloud.github.com/backbone/#Router

    http://documentcloud.github.com/backbone/#FAQ-events

    具体来说,我认为您想将一个事件处理程序(在您的路由器上)绑定到“route:nameOfYourRoute”,或者只是 :route”(如果您想在每个虚拟页面加载时触发您的逻辑)。

    希望对您有所帮助,如果我的猜测有误,请编辑您的问题以澄清。

    【讨论】:

    • 对类型-o 感到抱歉。我的意思是执行。是的,你正确地理解了我。我使用骨干路由器来运行基于 url 标签的页面。问题是我试图找到一种在视图呈现后运行代码的方法。在router中添加代码会触发逻辑,但是太早了,页面还没有渲染。
    • 我很困惑:你真的尝试过我的建议吗?路由事件在应用路由回调后触发;该代码实际上是callback && callback.apply(this, args); this.trigger.apply(this, ['route:' + name].concat(args));,因此您在事件处理程序中添加的任何逻辑在您的视图渲染后触发(当然假设您在路由的回调中调用渲染)。
    • 我找到了解决方案。我的路由器中有一条 if 语句,我注释掉了。这样,每次触发路由器功能时都会生成一个新视图,而不是使用“缓存”视图。解决方案如下。这是最优的吗?我也在尝试应用和理解您提出的解决方案。我在哪里添加代码?感谢您的耐心等待。
    • 很高兴你想通了 :-) 每次都创建一个新视图并没有错(除非你经常这样做并且不清理你的引用),但它似乎没有必要。通过注释掉if,您是在说“每次都创建一个新视图”,如果这是您想要的,那很好......但我认为您真正想要的只是重新渲染每次:您当前正在通过创建一个新视图、调用其初始化并因此触发其渲染来执行此操作。如果你保留你的 if,你的代码可能会更干净,但是在其中添加了一个 else 块,它执行了 this.homeView.render();
    • P.S.您可能需要考虑编辑您的问题以使事情更清楚,并(仅)包含相关代码,仅供可能来到这里的未来读者使用。此外,您应该接受自己的答案,这样这个问题就不会留在未回答的问题队列中。但是,如果您觉得我的回答有用,欢迎您点赞 :-)
    猜你喜欢
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2014-06-23
    • 1970-01-01
    相关资源
    最近更新 更多