Mojito项目实战:构建复合Mojit应用

Mojito项目实战:构建复合Mojit应用

【免费下载链接】mojito [archiving soon] Yahoo! Mojito Framework 【免费下载链接】mojito 项目地址: https://gitcode.com/gh_mirrors/mo/mojito

前言

本文将深入探讨如何使用Mojito框架构建包含多个Mojit组件的复合应用。我们将创建一个图片浏览应用,包含图片列表和详情两个Mojit组件,实现组件间的交互和数据共享。

项目概述

我们将构建一个Flickr图片浏览应用,主要包含两个核心功能:

  1. 图片列表Mojit:显示Flickr图片缩略图,支持分页浏览
  2. 图片详情Mojit:显示选中图片的详细信息

这两个Mojit将协同工作,当用户点击列表中的缩略图时,详情Mojit将展示对应图片的详细信息。

环境准备

在开始之前,请确保已经完成Mojito的安装和基础配置。如果尚未完成,请参考相关文档进行设置。

创建基础应用

首先创建一个新的Mojito应用:

mojito create app flickr-list
cd flickr-list

构建图片列表Mojit

1. 创建Mojit

mojito create mojit simple PagedFlickr
mkdir mojits/PagedFlickr/lang
mkdir mojits/PagedFlickr/assets

2. 控制器实现

控制器主要负责处理业务逻辑,这里我们需要实现分页功能和图片数据获取:

YUI.add('PagedFlickr', function(Y, NAME) {
    var PAGESIZE = 6;
    
    Y.mojito.controllers[NAME] = {
        index: function(ac) {
            // 处理分页参数
            var page = ac.params.getFromMerged('page');
            var start = (page-1) * PAGESIZE;
            
            // 获取图片数据
            ac.models.get('ModelFlickr').getFlickrImages('mojito', start, PAGESIZE, function(err, images) {
                // 构建视图数据
                var data = {
                    images: images,
                    // 分页控制
                    prev: { url: selfUrl(ac, 'flickr', { page: page-1 } ) },
                    next: { url: selfUrl(ac, 'flickr', { page: page+1 } ) }
                };
                
                // 为图片添加详情链接
                Y.Array.each(images, function(image) {
                    image.detail_url = '/detail/image/' + image.id;
                });
                
                ac.done(data);
            });
        }
    };
    
    // 辅助函数:生成URL
    function selfUrl(ac, mojitType, mods) {
        var params = Y.mojito.util.copy(ac.params.getFromMerged());
        for (var k in mods) {
            params[k] = mods[k];
        }
        return ac.url.make(mojitType, 'index', Y.QueryString.stringify(params));
    }
}, '0.0.1', {requires: ['mojito-models-addon', 'mojito-util', 'querystring-stringify', 'ModelFlickr']});

3. 共享模型实现

我们使用共享模型来获取Flickr图片数据:

YUI.add('ModelFlickr', function(Y, NAME) {
    Y.mojito.models[NAME] = {
        getFlickrImages: function(queryString, start, count, callback) {
            // 使用YQL查询Flickr API
            var q = 'select * from flickr.photos.search(' + start + ',' + count + ') where text="' + queryString + '"';
            Y.YQL(q, function(rawYqlData) {
                // 处理返回数据
                var photos = [];
                Y.Array.each(rawYqlData.query.results.photo, function(rawPhoto) {
                    photos.push({
                        id: rawPhoto.id,
                        title: rawPhoto.title || "[" + queryString + "]",
                        url: buildFlickrUrlFromRecord(rawPhoto)
                    });
                });
                callback(null, photos);
            });
        }
    };
    
    // 辅助函数:构建Flickr图片URL
    function buildFlickrUrlFromRecord(record) {
        return 'http://farm' + record.farm + '.static.flickr.com/' + 
               record.server + '/' + record.id + '_' + record.secret + '.jpg';
    }
}, '0.0.1', {requires: ['yql', 'jsonp-url']});

4. 视图模板

使用Mustache模板引擎渲染图片列表:

<div id="{{mojit_guid}}">
    <ul class="pics">
        {{#images}}
            <li class="pic">
                <a href="{{detail_url}}">
                    <img src="{{url}}" alt="{{title}}"/>
                </a>
            </li>
        {{/images}}
    </ul>
    <div id="paginate">
        {{#prev}}<a href="{{{url}}}">{{title}}</a>{{/prev}}
        {{#next}}<a href="{{{url}}}">{{title}}</a>{{/next}}
    </div>
</div>

5. 样式设计

为图片列表添加基本样式:

.pics .pic img {
    height: 60px;
    width: 60px;
}
ul.pics {
    list-style-type: none;
}
ul.pics .pic { 
    padding: 1px;
}
#paginate span { 
    margin:1em; 
}

构建图片详情Mojit

1. 创建Mojit

mojito create mojit simple FlickrDetail
mkdir mojits/FlickrDetail/lang
mkdir mojits/FlickrDetail/assets

2. 控制器实现

详情Mojit控制器处理图片详情请求:

YUI.add('FlickrDetail', function(Y, NAME) {
    Y.mojito.controllers[NAME] = {
        index: function(ac) {
            var imageId = ac.params.getFromMerged('image') || '0';
            
            // 参数验证
            if (!imageId.match(/^\d+$/)) {
                return ac.done({ type: 'error', message: 'Invalid image ID' });
            }
            
            // 获取图片详情
            ac.models.get('ModelFlickr').getFlickrDetail(imageId, function(err, details) {
                if (err) return ac.error(err);
                
                // 处理详情数据
                details.intl = {
                    DATE_POSTED: ac.intl.lang('DATE_POSTED'),
                    // 其他国际化字段
                };
                
                ac.done(details);
            });
        }
    };
}, '0.0.1', {requires: ['mojito-models-addon', 'mojito-intl-addon', 'ModelFlickr']});

3. 扩展共享模型

在原有模型基础上添加获取详情的方法:

getFlickrDetail: function(imageId, callback) {
    var q = 'select * from flickr.photos.info where photo_id="' + imageId + '"';
    Y.YQL(q, function(rawYqlData) {
        var photo = rawYqlData.query.results.photo;
        photo.urls.image = {
            type: 'image',
            content: buildFlickrUrlFromRecord(photo)
        };
        callback(null, photo);
    });
}

4. 视图模板

详情页模板展示图片信息:

<div class="FlickrDetail">
    <div class="img">
        <img src="{{urls.image.content}}" alt="{{title}}"/>
    </div>
    <table>
        <tr class="title">
            <th>{{intl.TITLE}}</th>
            <td>{{#title}}{{.}}{{/title}}{{^title}}{{intl.TITLE_NONE}}{{/title}}</td>
        </tr>
        <tr class="description">
            <th>{{intl.DESCRIPTION}}</th>
            <td>{{#description}}{{.}}{{/description}}{{^description}}{{intl.DESCRIPTION_NONE}}{{/description}}</td>
        </tr>
        <!-- 其他信息展示 -->
    </table>
</div>

应用配置

1. 路由配置

定义应用的路由规则:

[
    {
        "settings": ["master"],
        "flickr_by_page": {
            "verbs": ["get"],
            "path": "/flickr/page/:page",
            "call": "flickr.index"
        },
        "flickr_base": {
            "verbs": ["get"],
            "path": "/flickr",
            "param": "page=1",
            "call": "flickr.index"
        },
        "detail": {
            "verbs": ["get"],
            "path": "/detail/image/:image",
            "call": "detail.index"
        }
    }
]

2. 应用配置

注册Mojit组件:

[
    {
        "settings": ["master"],
        "specs": {
            "flickr": {
                "type": "HTMLFrameMojit",
                "config": {
                    "child": {
                        "type": "PagedFlickr"
                    }
                }
            },
            "detail": {
                "type": "HTMLFrameMojit",
                "config": {
                    "child": {
                        "type": "FlickrDetail"
                    }
                }
            }
        }
    }
]

运行与测试

启动应用服务器后,可以访问以下URL测试应用:

  1. 图片列表页:/flickr
  2. 图片详情页:/detail/image/{image_id}

进阶优化

  1. 客户端渲染优化:可以添加客户端JavaScript实现无刷新加载详情
  2. 错误处理增强:完善各种边界情况的错误处理
  3. 性能优化:添加缓存机制减少YQL请求
  4. 响应式设计:使界面适配不同设备屏幕

总结

通过本文,我们学习了如何在Mojito框架中:

  1. 创建包含多个Mojit的复合应用
  2. 实现Mojit间的数据共享和交互
  3. 使用共享模型减少代码重复
  4. 配置路由和应用结构

这种架构模式可以扩展到更复杂的应用场景,为构建模块化、可维护的Web应用提供了良好基础。

【免费下载链接】mojito [archiving soon] Yahoo! Mojito Framework 【免费下载链接】mojito 项目地址: https://gitcode.com/gh_mirrors/mo/mojito

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值