基于 flask 框架的模拟instagram 图片分享网站的开发 3

1. 摘要

这次添加的功能是 实现首页和 个人信息页面的异步加载功能
传送门:
基于 flask 框架的模拟instagram 图片分享网站的开发 2
基于 flask 框架的模拟instagram 图片分享网站的开发 1

2. 流程

2.1 profile.js 分析

  1. 这里需要编写相应的js 代码, 主要由前端提供, 虽然是前端提供的代码, 我们还是需要读懂它, 在必要的时候做相应的修改
  2. 代码中, oExports 相当于是一个字典, 记录了关键字 与相应处理函数之间的映射关系, ie, 使用initialize 调用的时候, 本质就是在执行 fInitialize 函数调用
  3. 在 fInitialize 中, 我们首先找到 需要加载 图片 的区域 ‘div.js-image-list’, 初始化相应数据, 并为元素 ‘.js-load-more’ 添加点击事件
  4. fTpl 中, oData 对应着 传入的 json 数据, 当然也可以是自己构建的字典数据 ( 在 index 中 加载评论的时候, 我们就需要自行加载自己的 comments 字典数据)
  5. fRequestData 用来请求数据, 这里面将 需要异步加载的 html 代码写入进来
$(function () {
    var oExports = {
        initialize: fInitialize,
        // 渲染更多数据
        renderMore: fRenderMore,
        // 请求数据
        requestData: fRequestData,
        // 简单的模板替换
        tpl: fTpl
    };
    // 初始化页面脚本
    oExports.initialize();

    function fInitialize() {
        var that = this;
        // 常用元素
        that.listEl = $('div.js-image-list');
        // 初始化数据
        that.uid = window.uid;
        that.page = 1;
        that.pageSize = 6;
        that.listHasNext = true;
        // 绑定事件
        $('.js-load-more').on('click', function (oEvent) {
            var oEl = $(oEvent.currentTarget);
            var sAttName = 'data-load';
            // 正在请求数据中,忽略点击事件
            if (oEl.attr(sAttName) === '1') {
                return;
            }
            // 增加标记,避免请求过程中的频繁点击
            oEl.attr(sAttName, '1');
            that.renderMore(function () {
                // 取消点击标记位,可以进行下一次加载
                oEl.removeAttr(sAttName);
                // 没有数据隐藏加载更多按钮
                !that.listHasNext && oEl.hide();
            });
        });
    }

    function fRenderMore(fCb) {
        var that = this;
        // 没有更多数据,不处理
        if (!that.listHasNext) {
            return;
        }
        that.requestData({
            uid: that.uid,
            page: that.page + 1,
            pageSize: that.pageSize,
            call: function (oResult) {
                // 是否有更多数据
                that.listHasNext = !!oResult.has_next && (oResult.images || []).length > 0;
                // 更新当前页面
                that.page++;
                // 渲染数据
                var sHtml = '';
                $.each(oResult.images, function (nIndex, oImage) {
                    sHtml += that.tpl([
                        '<a class="item" href="/image/#{id}">',
                            '<div class="img-box">',
                                '<img src="/#{url}">',
                            '</div>',
                            //'<div class="img-mask"></div>',
                            //'<div class="interaction-wrap">',
                            //    '<div class="interaction-item"><i class="icon-comment"></i>#{comment_count}</div>',
                            //'</div>',
                        '</a>'].join(''), oImage);
                });
                sHtml && that.listEl.append(sHtml);
            },
            error: function () {
                alert('出现错误,请稍后重试');
            },
            always: fCb
        });
    }

    function fRequestData(oConf) {
        var that = this;
        var sUrl = '/profile/images/' + oConf.uid + '/' + oConf.page + '/' + oConf.pageSize + '/';
        $.ajax({url: sUrl, dataType: 'json'}).done(oConf.call).fail(oConf.error).always(oConf.always);
    }

    function fTpl(sTpl, oData) {
        var that = this;
        sTpl = $.trim(sTpl);
        return sTpl.replace(/#{(.*?)}/g, function (sStr, sName) {
            return oData[sName] === undefined || oData[sName] === null ? '' : oData[sName];
        });
    }
});

2.2 建立请求的路由

  1. 这部分需要和 相应的js 文件中 的 fRequestData 定义的路由保持一致, 并输出json 数据
@app.route('/profile/images/<int:id>/<int:page_num>/<int:per_page>/')
@login_required
def profile_paginate(id, page_num, per_page):
    user = User.query.get(id)
    paginate = user.images.paginate(page=page_num, per_page=per_page, error_out=False)
    map = {'has_next' : paginate.has_next}
    images = []
    for image in paginate.items:
        imgvo = {'id':image.id, 'url':image.url}
        images.append(imgvo)
    map['images'] = images
    return json.dumps(map)

2.3 index 页面

同理可以编写index 页面的异步加载功能

3. 处理效果

这里写图片描述
这里写图片描述

4. 遇到的问题

  1. 由于jquery 代码不熟悉, 加载的时候, 评论部分无法加载, 后来才想到, 应该修改 需要传递的 json 信息, 将评论作为一个列表传送
    这里写图片描述
    相应的 renderMore 部分代码:
   function fRenderMore(fCb) {
        var that = this;
        // 没有更多数据,不处理
        if (!that.listHasNext) {
            return;
        }
        that.requestData({
            uid: that.uid,
            page: that.page + 1,
            pageSize: that.pageSize,
            call: function (oResult) {
                // 是否有更多数据
                that.listHasNext = !!oResult.has_next && (oResult.images || []).length > 0;
                // 更新当前页面
                that.page++;
                // 渲染数据
                var sHtml = '';
                $.each(oResult.images, function (nIndex, oImage) {
                    sHtml_part1 = that.tpl([
                         '<article class="mod">',
            '<header class="mod-hd">',
                '<time class="time">#{ images.create_date }</time>',
                '<a href="/profile/#{image_user_id}" class="avatar">',
                 '   <img src="/#{image_user_head_url}">',
                '</a>',
                '<div class="profile-info">',
                    '<a title="#{image_user_username}" href="/profile/#{image_user_id}">#{image_user_username}</a>',
                '</div>',
            '</header>',
            '<div class="mod-bd">',
                '<div class="img-box">',
                    '<a href = "/image/#{image_id}">',
                    '<img src="/#{image_url}">',
               ' </div>',
           ' </div>',
           ' <div class="mod-ft">',
              '  <ul class="discuss-list">',
                   ' <li class="more-discuss">',
                       ' <a>',
                           ' <span>全部 </span><span class="">#{image_comments_length}</span>',
                            '<span> 条评论</span></a>',
                    '</li>'].join(''), oImage);
                    sHtml_part2 = ' ';

                    // 解析评论列表中的数据
                    for (var ni = 0; ni < oImage.image_comments_length; ni++){
                        dict = {'comment_user_username':oImage.comment_user_username[ni], 'comment_user_id':oImage.comment_user_id[ni],
                            'comment_content':oImage.comment_content[ni] };
                        sHtml_part2 += that.tpl([
                        '    <li>',
                            '    <a class="_4zhc5 _iqaka" title="#{comment_user_username}" href="/profile/#{comment_user_id}" data-reactid=".0.1.0.0.0.2.1.2:$comment-17856951190001917.1">#{comment_user_username}</a>',
                            '    <span>',
                            '        <span>#{comment_content}</span>',
                           '     </span>',
                         '   </li>',
                             ].join(''), dict);
                    }

                    sHtml_part3 =    that.tpl([
              '  </ul>',
               ' <section class="discuss-edit">',
                  '  <a class="icon-heart"></a>',
                  '  <form>',
                   '     <input placeholder="添加评论..." type="text">',
                  '  </form>',
                  '  <button class="more-info">更多选项</button>',
               ' </section>',
           ' </div>',

       ' </article>  '
                    ].join(''), oImage);
                    sHtml += sHtml_part1 + sHtml_part2 + sHtml_part3;
                });
                sHtml && that.listEl.append(sHtml);
            },
            error: function () {
                alert('出现错误,请稍后重试');
            },
            always: fCb
        });
    }
  1. 修改js 代码之后, 直接输入网址, 不会立即生效, 需要 刷新浏览器(ps, 被这个坑了好久)

5. 工程地址

https://code.csdn.net/zhyh1435589631/instagram_simulation/tree/master

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值