TP+angular+oc.lazyLoad 前端组件式开发构思

浏览:9511 最后更新:2016-01-28 15:29 分类:示例 关键字: TP+angular+oc.lazyLoad 前端组件式开发构思
基本构思
1.TP 负责Service 处理,静态页面处理,Api等。解决angular seo不友好部分。
2.angular+oc.lazyLoad负责前端组件化拆分调用等。
哪里需要哪里掉,哪个模板适合调用哪个模板思想。
3.目前构思是我之前的一个项目尝试,由于不想用sea,requirejs 需要js封装类型的异步加载方式,所以尝试了angular +oc独立组件方式载入。
目前项目已完成,特发布感想。有什么想法都可以留言讨论。

分享局部代码 只是局部功能展示
局部目录结构的:

1.脚本依赖,jquery,B3(有它最好),angularjs,angular 插件 oc.lazyload,其他个别插件,哪个组件用到组件内部注入。项目启动App.js入口
2.页面初始化基本js常量初始化操作等。
设置好模板目录静态文件目录等基本变量<script type="text/javascript">
            var HTTP_HOST = "__HTTP_HOST__";
            var PUBLIC_URL = HTTP_HOST + "__PUBLIC__";
            var SERVICE_HOST = "__SERVICE_HOST__";
            var TEMPLATE_URL = "__TEMPLATE_URL__";
            var MODULE_URL = "__MODULE_URL__";
            var CDN_HOST='__CDN_HOST__';//图片,静态文件前缀
            var _G=''//后台一些信息json传值至前台存入改变量
        </script>
3.App.js 入口js初始化angular.module('common.ctrl', []);//控制器,组件等。
angular.module("common.directives", []);//公共指令等
angular.module('common', ['common.ctrl', 'common.directives']);//common 依赖相关js分层 自己决定
var routeApp = angular.module("app", ["oc.lazyLoad", "common"]);

//_G 全局变量。设置一些全局参数
//初始化服务
routeApp.config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) {
        $ocLazyLoadProvider.config({
            debug: _G['debug'],
            events: _G['debug'],
            cssFilesInsertBefore: 'ng_load_plugins_before' // load the above css files before a LINK element with this ID. Dynamic CSS files must be loaded between core and theme css files
            , modules: []
        });
    }]);

routeApp.run(["$rootScope", function($rootScope) {
        $rootScope.pageLoaded = true;//载入状态控制
        $rootScope._G = _G;
        $rootScope.CDN_HOST = CDN_HOST;
        //...更多全局变量存入$rootScope
        $rootScope.SERVICE_HOST = SERVICE_HOST;
    }]);

//最高Controller 一些全局操作
routeApp.controller('AppCtrl', ['$scope', 'uiTool', '$rootScope', 'BbsService','$element', function($scope, uiTool, $rootScope, BbsService, $element) {
        if ($rootScope._G['debug']) {
            console.info('$rootScope:');
            console.info($rootScope);
        }
        $element.find('.fancybox').fancybox();
    }]);
4.组件载入方式。
4.1比如页面需要一个论坛发帖组件, 采用 oc-lazy-load 指令载入组件入口模板<!--发帖组件-->
            <div class="row" oc-lazy-load='{"template":MLMJS+"/tpl/ViewThreadCtrl.html"}'>
                <section ng-include="'tpl/ViewThreadCtrl.html'"></section>
            </div>
4.2论坛发帖组件入口模板 \js\tpl\ViewThreadCtrl.html
模板key: tpl/ViewThreadCtrl.html
启动模板 包含相关js/css/等依赖信息
模板/css/img/js等这些都在启动模板内关联依赖。并且将这些资源自动加入缓存,那就是说这些依赖js/css都是载入一次的。
前台展示模板可以根据多种环境调用不同的模板key,控制器一个就可以了。

\js\tpl\ViewThreadCtrl.html<!--ocLazyLoad 载入模板方式-->
<!--发帖帖子-->
<!-- The basic File Upload plugin -->
<script id="tpl/ViewThreadCtrl.html" type="text/ng-template">
    <section oc-lazy-load='{"files": [MLMPLUG+"/bootbox/bootbox.min.js",MLMPLUG+"/fileupload/css/jquery.fileupload.css",MLMPLUG+"/fileupload/js/vendor/jquery.ui.widget.js",MLMPLUG+"/fileupload/js/jquery.iframe-transport.js",MLMPLUG+"/fileupload/js/jquery.fileupload.js",MLMPLUG+"/fancybox/source/jquery.fancybox.js",MLMPLUG+"/fancybox/source/jquery.fancybox.css",MLMJS+"/ctrl/ViewThreadCtrl.js"]}'>
        <div ng-controller="NewViewThreadCtrl">
            <section ng-include="'tpl/ViewThread/NewThreadBox.html'"></section>
        </div>
    </section>
</script>
<!--发帖框-->
<script id="tpl/ViewThread/NewThreadBox.html" type="text/ng-template">
    <div class="item-horizontal bg-gray">
        <div class="text-title">我想说两句</div>
        <div>
            <select ng-if="forumCategory" onchange="angular.element(this).scope().setForumCategory(this)">
                <option value="" ng-click="setForumCategory(0)">请选择讨论分类</option>
                <option value="{{key}}" ng-repeat="(key,value) in forumCategory">
                    {{value}}
                </option>
            </select>
            <input style="width: 696px;" ng-model="post.subject" placeholder="一句话说清楚你的问题,比如“帮我看看户型图,我家的一居室能否改成两居室?”">
            <textarea class="reply-box" placeholder="对问题进行补充,详细描述你的疑问或者经验。~" rows="3" ng-model="post.message"></textarea>
            <!--aids:{{post.aids|json}}-->
            <section ng-controller="UploadFilesCtrl">
                <div class="reply-submit clearfix">
                    <div class="pull-left icon-smile" ng-click="selectImg()">
                        <div class="btn btn-success fileinput-button">
                            <i class="glyphicon glyphicon-plus"></i> <span>选择图片...</span>
                            <input type="file" name="Filedata" multiple/>
                        </div>
                    </div>
                    <div class="pull-right">
                        <button ng-disabled="newThreadLoading" type="button" ng-click="newThread(0)" class="btn btn-red" ng-bind="newThreadLoading?'提交中...':'提交'"></button>
                    </div>
                </div>
                <div class="file-list row">
                    <div class="topic-upload" ng-repeat="(key,item) in imgList" ng-if="!item.del">
                        <span class="up-info" ng-hide="1">{{item.file.name}}<br></span>
                    <span class="up-waiting">
                        <img ng-if="item.loading" ng-src="{{MLMIMG+'/loading5.gif'}}">
                    </span> <span class="up-process"></span>
                    <span class="up-photo">
                        <a ng-click="openFancyBox()" ng-if="item.result.obj.url||item.base64Img" class="fancybox-thumbs" data-fancybox-group="thumb" href="{{item.result.obj.url?item.result.obj.url:item.base64Img}}">
                            <img ng-if="item.result.obj.url||item.base64Img" ng-src="{{item.result.obj.url?item.result.obj.url:item.base64Img}}" style="display: inline;">
                        </a>
                    </span> <a ng-if="item.result.obj.aid" class="up-del" ng-click="delImg(item.result.obj.aid)">
                        <img ng-src="{{MLMIMG+'/upload-del-s.png'}}"> </a>
                    </div>
                </div>
            </section>
        </div>
    </div>
</script>
组件控制器
\js\ctrl\ViewThreadCtrl.js/**
 * 发帖插件
 * 插件引入
 <div oc-lazy-load='{"template":MLMJS+"/tpl/ViewThreadCtrl.html"}'>
 <section ng-include="'tpl/ViewThreadCtrl.html'"></section>
 </div>
 */
angular.module('common.ctrl')
/**
 * sub 图片上传操作
 */
    .controller('UploadFilesCtrl', ['$scope', 'uiTool', '$rootScope', 'BbsService', '$element', function ($scope, uiTool, $rootScope, BbsService, $element) {
        $scope.uploadInput = $element.find("input[type='file']");
        var url = '';
        imgexts = typeof imgexts == 'undefined' ? '.jpg, .jpeg, .gif, .png,.bmp' : imgexts;
        var imgIndex = 1;
        $scope.initInput = function () {
            $scope.uploadInput.fileupload({
                url: url,
                dataType: 'json',
                acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
                autoUpload: false,
                formData: [
                    {name: 'uid', value: $rootScope._G['uid']},
                    {name: 'hash', value: $rootScope._G['uploadhash']}
                ]
            }).on('fileuploadadd', function (e, data) {
                if (uiTool.login()) {
                    data._index = imgIndex;
                    $scope.imgList[imgIndex] = {file: data.files[0], loading: true};
                    $scope.readerFile(imgIndex);
                    imgIndex++;
                    $scope.$apply();
                    data.submit();
                }
            }).on('fileuploadprocessalways', function (e, data) {
                //console.info('fileuploadprocessalways');
                //console.info(data);
            }).on('fileuploadprogressall', function (e, data) {
            }).on('fileuploaddone', function (e, data) {
                $scope.imgList[data._index]['result'] = $scope.uploadBack(data.result.msg);
                if ($scope.imgList[data._index].result.code != 200) {
                    uiTool.alert($scope.imgList[data._index].file.name + '<br>' + $scope.imgList[data._index].result.msg, 'error');
                    $scope.imgList[data._index]['del'] = true;
                }
                $scope.updateUsedAids();
                $scope.imgList[data._index].loading = false;
                $scope.$apply();
            }).on('fileuploadfail', function (e, data) {
                //console.info('fileuploadfail');
                //console.info(data);
            });
        }
        /**
         * 删除图片
         * @param aid
         */
        $scope.delImg = function (aid) {
            if (!uiTool.login()) {
                return false;
            }
            var postData = {
                uid: $rootScope._G['uid'] ? $rootScope._G['uid'] : 0,
                pid: $rootScope._G['pid'] ? $rootScope._G['pid'] : 0,
                tid: $rootScope._G['tid'] ? $rootScope._G['tid'] : 0,
                aid: aid
            };
            if ($scope.loading.delloading[aid]) {
                return;
            }
            $scope.loading.delloading[aid] = true;
            BbsService.fetch(postData, 'deleteattach').success(function (data) {
                BbsService.callback(data, function () {
                    if (data.obj > 0) {
                        for (var i in $scope.imgList) {
                            if ($scope.imgList[i].result && $scope.imgList[i].result.obj && $scope.imgList[i].result.obj.aid == aid) {
                                $scope.imgList[i]['del'] = true;
                                break;
                            }
                        }
                        $scope.updateUsedAids();
                        //$scope.$apply();
                    }
                });
                $scope.loading.delloading[aid] = false;
            }).error(function () {
                $scope.loading.delloading[aid] = false;
                uiTool.alert('未知错误,请联系管理员');
            })
        };
        /**
         * html5 图片预读
         * @param index
         * @returns {boolean}
         */
        $scope.readerFile = function (index) {
            if (typeof FileReader == 'undefined') {
                console.info('你的浏览器不支持FileReader接口!');
                return false;
            }
            var file = $scope.imgList[index].file;
            if (!/image\/\w+/.test(file.type)) {
                console.info('格式错误');
                return false;
            }
            var reader = new FileReader();
            reader.readAsDataURL(file);
            //reader.readAsBinaryString(file);
            //reader.readAsText(file);
            reader.onload = function (e) {
                $scope.imgList[index]['base64Img'] = this.result;
            }
        };
        /**
         * 清理图片
         */
        $scope.clearAttache = function () {
            BbsService.fetch({}, 'clearattache');
        };
        /**
         * 图片预览插件
         */
        $scope.openFancyBox = function () {
            $element.find('.fancybox-thumbs').fancybox();
        };
        /**
         * 上传图片回调信息处理
         * @param result
         * @returns {{code: number, msg: string, obj: null}}
         */
        $scope.uploadBack = function (result) {
            return result;
        };
        $scope.updateUsedAids = function () {
            $scope.aids = [];
            angular.forEach($scope.imgList, function (value, key) {
                if (value.result && value.result.code == 200 && !value.del) {
                    $scope.aids.push({aid: parseInt(value.result.obj.aid), description: value.result.obj.name});
                }
            });
            $scope.eventParent($scope.aids);
        }
        //通知父类控制器更新图片上传id
        $scope.eventParent = function (aids) {
            $scope.$emit('eventAidsChanged', aids);
        }
        $scope.clearAttache();
        $scope.initInput();
    }])
/**
 * parent 发帖操作
 */
    .controller('NewViewThreadCtrl', ['$scope', 'uiTool', '$rootScope', 'BbsService', '$element', function ($scope, uiTool, $rootScope, BbsService, $element) {
        $scope.post = {message: '', fid: $rootScope._G['fid'], subject: '', typeid: 0, aids: []};
        $scope.list = [];
        $scope.obj = {};
        $scope.newThreadLoading = false;
        $scope.forumCategory = [];
        $scope.init = function () {
            //获取版块分类
            BbsService.fetch({fid: $scope.post.fid}, 'getForumCategory').success(function (data) {
                $scope.forumCategory = data.list;
            });
        }
        $scope.setForumCategory = function (i) {
            if (i == 0) {
                $scope.post.typeid = 0;
                return;
            }
            $scope.post.typeid = angular.element(i).val();
        }
        //监听图片上传id
        $scope.$on('eventAidsChanged', function (event, data) {
            if (data && angular.isArray(data) && data.length > 0) {
                $scope.post.aids = data;
            }
        });
        $scope.newThread = function () {
            if (!uiTool.login()) {
                return false;
            }
            if ($scope.post.subject == '') {
                uiTool.alert('请输入您想提的问题', 'warning');
                return;
            }
            if ($scope.post.message == '') {
                uiTool.alert('请输入问题描述', 'warning');
                return;
            }
            $scope.newThreadLoading = true;
            BbsService.newthread($scope.post).success(function (data) {
                if (data.code == 200 && data.obj && data.obj.tid > 0) {
                    data.url = BbsService.fetchUrl({tid: data.obj.tid}, 'newThread');
                } else {
                    $scope.newThreadLoading = false;
                }
                BbsService.callback(data, function () {

                });
            }).error(function () {
                $scope.newThreadLoading = false;
                uiTool.alert('未知错误,请联系管理员');
            });
        };
        $scope.init();
    }]);
基本上组件流程就完成。
这样理论上所以不相关的seo 等操作都可做成组件。
单场景应用等也可参考这种插件引入方式。真正做到一个插件。完全独立哪需要引哪里。
评论( 相关
后面还有条评论,点击查看>>