• angularJs scope的简单模拟


    必要: JS MVC中, 模块间的数据不能相互影响, 只有这样才能有效的保证模块的复用性.

    预期效果: angularJs很好的展现了这一点,它的效果类似于JS词法作用域:

      在一个函数中,内嵌函数可以访问外部函数的变量,而外部函数不能访问内部函数的变量 

    思路: 1 给每个controller绑定一个scope对象,scope存该模块的属性

       2 如果controller有父controller,则为scope对象增加一个$parent属性指向父controller的scope对象

       3 增加一个代理函数, 把函数和方法绑定作用域

    代码: 

    <script src="jquery.js"></script>
    
    <div ctrl="parent">
        父作用域:
        <input type="button" click="pfn()" value="自己的方法">
        <input type="button" click="cfn()" value="调用子方法">
        </hr>
        <div ctrl="child">
            子作用域:
            <input type="button" click="cfn()" value="自己的方法">
            <input type="button" click="pfn()" value="调用父方法">
        </div>
    </div>
    
    <script>
        var angular = (function(){
            var agl = {};
            agl.compile = function(){
                //初始化controller
                $("[ctrl]").each(function(){
                    var ctrl = $(this).attr("ctrl");
                    if(!window[ctrl])
                        throw new Error("不存在"+ctrl+"的函数");
                    var scope = newScope(ctrl);
                    //绑定函数
                    $("[click]",this).each(function(){
                        var fname = $(this).attr("click").replace("(","").replace(")","");
                        $(this).unbind().click(execInScope(fname,scope));
                    });
                });
            }
            
            function newScope(ctrl){
                var ctrlFn = window[ctrl];
                var scope = ctrlFn.$scope = {};
                //为scope对象增加属性
                ctrlFn(scope);
                inScopeChain(ctrl,scope);
                return scope;
            }
    
            //判断是否有parent,有则存入$parent属性中
            function inScopeChain(_self,scope,last){
                var p;
                if(last) p = last.parent();
                else     p = $('[ctrl='+_self+']').parent();
                if(p){
                    var ps = p.attr("ctrl");
                    if(ps){
                        scope.$parent = window[ps].$scope;
                        return;
                    }
                    //判断是否到达根节点
                    if(p[0] != $("body")[0])
                        arguments.callee.call(null,_self,scope,p);
                }
                return;
            }
    
            //绑定作用域中的函数
            function execInScope(fname,scope){
                var fn = scope[fname];
                //如果本作用域没就到父作用域去找
                while(!fn && scope.$parent){
                    fn = scope.$parent[fname];
                }
                if(fn)
                    return fn;
                else
                    return function(){alert("该作用域没有该方法");}
            }
    
            //dom加载完毕,开始编译
            window.onload = agl.compile;
    
            return agl;
        }())
    
    
        function parent($scope){
            $scope.pfn = function(){
                alert("父方法");
            }
        }
        
        function child($scope){
            $scope.cfn = function(){
                alert("子方法");
            }
        }
    </script>
  • 相关阅读:
    轮播图2
    点击按钮切换轮播图
    轮播图
    2016.5.5_十进制转二进制【ABAP】
    2016.4.26_longtext长文本【ABAP】
    2016.4.26_动态内表【ABAP】
    2016.4.26_下载abap代码【ABAP】
    2016.4.15_debug小技巧【ABAP】
    2016.4.1_js向controller传数据【笔记】
    2016.3.21_TABLE CONTROL【ABAP】
  • 原文地址:https://www.cnblogs.com/79home/p/3391294.html
Copyright © 2020-2023  润新知