【问题标题】:How to change a subview using the YUI App framework如何使用 YUI App 框架更改子视图
【发布时间】:2013-05-31 11:29:30
【问题描述】:

我是第一次使用 YUI App 框架创建一个应用程序。所以我仍在努力了解它是如何运作的。

我的应用将同时显示多个视图,这是通过使用嵌套视图完成的。导航应用程序时,应该可以只更改其中一个(子)视图,而无需重新渲染父视图。

我在这里创建了一个简单的例子:http://jsfiddle.net/casperskovgaard/BDqjz/6/

应用程序将呈现一个包含两个子视图的 HomePageView。一个菜单视图和一个内容视图。从菜单视图可以更改内容视图。

呈现主页的代码如下所示:

render: function () {
    Y.log('render homepage view');
    var container = this.get('container');

    container.setHTML(this.template());
    container.one('#menu').setHTML(new Y.MenuView().render().get('container'));
    container.one('#content').setHTML(this.get('content').render().get('container'));

    return this;
}

如果路线改变,内容视图也会改变。

因为现在是 HomePageView,并且每次更改路由时两个子视图都会重新渲染。

如何更改它,以便在单击菜单视图中的链接时仅重新呈现内容视图?

另外我对如何在子视图上使用容器属性有点困惑,任何提示将不胜感激

-卡斯帕

【问题讨论】:

    标签: javascript model-view-controller view yui


    【解决方案1】:

    根据第一个答案下的评论中的进一步描述,我仍然会从“views”属性中删除 MenuView 和其他子视图,因为它实际上仅用于将不会成为“activeView”的视图。

    我会将 HomePageView 设为“保留”视图,并使用传递给“showView”的选项对象的“回调”属性来告诉该视图要显示哪些内容。

    所以“视图”现在看起来像:

    views: {
        homePage: {type: 'HomePageView', preserve: true}
    }
    

    你的处理程序看起来像:

    handleFirst: function () {
        this.showView(
            'homePage',
            null,
            { 
                callback: function (view) { 
                    view.showContent(Y.FirstView); 
                }
            }
        );
    }
    

    我向 HomePageView 添加了一个方法,如下所示:

    showContent: function (ctr) {
        Y.log("HomePageView::showContent: " + ctr);
        var container = this.get('container');
    
        container.one('#content').setHTML((new ctr).render().get('container'));
    }
    

    这是最简单的情况,它需要将视图的构造函数放入内容区域并每次重新创建它等等。 HomePageView 的实例没有理由不能保留其子视图的缓存和仅在需要时创建它们,等等。无论哪种方式,关键是当底层视图成为顶层的“activeView”时,您可以使用回调来操作底层视图。 (或者,我这样做是为了在该视图上触发一个事件,而不是将某些内容传递给它,然后在视图上使用事件处理程序来完成脏活,但我不知道您对自定义事件有多满意.)

    http://jsfiddle.net/brianjmiller/eP7s2/2/

    希望能拍两部作品。

    【讨论】:

    • 如果您需要真正的子视图历史维护,那么您可以在 IRC 上通过#yui 停下来,向@hatch 询问他的待处理图库模块。 AFAIK,目前还没有一种简单的方法可以通过核心应用程序功能来做到这一点。 Y.App 非常期待一个单一的顶级“活跃”视图。我使用“控制器”类型的模块做了一些稍微不同的事情,该模块位于上一层并让应用实例触发事件,这些事件会冒泡并控制页面的其他部分。
    • 嗯,这似乎是我要找的。我现在唯一担心的是代码不是很优雅,因为 showView 方法总是会调用同一个视图(主页)。因此,从应用程序更改视图的想法转移到了视图。但我认为你是对的,App 需要一个活动视图。您在主页视图上使用自定义事件的替代想法很有趣。我会多玩一点,稍后再回来提供更多反馈。非常感谢到目前为止的帮助:-)
    【解决方案2】:

    这里的关键是,如果您总是希望为页面显示菜单并且只根据路由处理程序更改内容视图,那么您应该将 Y.App 配置中的“viewContainer”节点设置为#content DOM 节点。除此之外,它们应该显示与其路由直接关联的视图,而不是让您的路由处理程序 .showView 在主页上。所以 .handleFirst 会显示“firstView”。为了实现这一点,我将从应用程序的“views”属性中删除“homePage”和“menuView”,并在更高级别处理它们,这样它们只会发生一次,并且您已经将 viewContainer 节点渲染到实例化 Y.App 实例之前的 DOM。

    实际上你有两个阶段,

    1) 页面/应用加载:因此初始设置只发生一次,通过 HomePage 视图创建页面,然后创建应用并将两者挂钩,

    2) 内容加载:您的应用实例通过路由处理所有这些,并且只影响内容“窗格”。

    var mymainview = new Y.HomePageView().render();
    Y.one("body").append(mymainview.get("container"));
    
    var myapp = new Y.MyApp({
        transitions: true,
        viewContainer: "#content"
    });
    
    myapp.render();
    

    对您的小提琴的示例编辑:

    http://jsfiddle.net/brianjmiller/W74uc/1/

    有关 viewContainer 的信息,请参阅 http://yuilibrary.com/yui/docs/app/#rendering-an-app。

    (对于您的子视图查询,您应该打开一个单独的更具体的问题。)

    【讨论】:

    • 感谢@Brian 的回答,但这并不是我所需要的。菜单视图不是静态的。我需要同时在页面上查看多个视图,并且只能呈现其中一个。在您提供的示例中,页面上只有一个活动视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多