netView实现依赖另一套环境的组件

每一种前端框架,大致都有netView这个预制体,大概相当于HttpImageView+加载包功能。以前的文章我们介绍过弹屏时的view使用的就是netView这个预制体,它让我们很灵活的实现在弹屏时加载各种各样的图片的功能,而这些图片并不需要放在App本地包中,对于缩减App大小和运营人员的灵活配置大有好处。
我们进一步的想,如果这个netVIew需要实现更复杂的功能怎么办?例如签到,小游戏等,一般的netView肯定无法实现我们想要的功能,很显然,我们需要对netView进行改进。
前面我们说到,netView是有加载包的功能的,当我们把想要实现的功能写进包里后,在将包解析后显示在netView中,这个问题就愉快的解决了。但是在这其中,我们肯定会遇到一个环境不同的问题,就是外层的netView所属环境为我们App运行的环境,里面各种环境变量自有一套,早就有我们的App封装好了,而对于我们要实现特有功能的包则不同,它是通过http下载到本地后,引擎在将其解包,渲染出来的,因此对于包来说,他的环境就是它自己,那么,我们要在包中使用一些全局变量怎么办呢?很显然,每一个包用什么就导入什么,每一个包中我们都要写大量同样的代码,emmm,有点难受,如果进一步想,我们能不能将这些用到的全局变量单独提出来,(实际上,这些全局变量与我们的App全局变量差不多,只不过为了便于维护,我们单独提出一份只针对包的环境)用一个组件将其加载进来,这样,我们的netView只需绑定我们的组件就可以了。

function        PkgNetViewEnvironment:setPkgNetViewEnvironment(object,data)
    self.Env = data or {};
end

每种框架写组件的方式不一样,这里我们只提取关键部分,这里是组件的导出方法,我们需要在外部设置好我们的Env,即包要用到的各种环境变量。接着:

---绑定导出的方法 
function PkgNetViewEnvironment:bind(object)
    for i,v in ipairs(exportInterface) do
        object:bind_method(self, v,   handler(self, self[v]));
    end
    local holderDelegate = {
        on_load = function(netView,view)
            getfenv(view.ctor).Env = self.Env;
            if object.on_load then
                object:on_load(view);
            end
            if view.on_load then
                view:on_load(self.Env)
            else
                if view.getUI then
                    local ui = view:getUI();
                    if ui.on_load then
                        ui:on_load(self.Env)
                    end
                end
            end
        end,
        on_fail = function(netView,errMsg)
            if object.on_fail then
                object:on_fail(errMsg);
            end
        end
    }

    local mergeDelegate = function ( value )
        if not value then
            return holderDelegate
        end
        -- delegate注入
        if value ~= holderDelegate then
            local oldOnLoad = value.on_load
            value.on_load = function ( ... )
                holderDelegate.on_load( ... )
                if oldOnLoad then
                    oldOnLoad( ... )
                end
            end
            local oldOnFail = value.on_fail
            value.on_fail = function ( ... )
                holderDelegate.on_fail( ... )
                if oldOnFail then
                    oldOnFail( ... )
                end
            end
            return value
        end
        return holderDelegate
    end
    object.delegate = mergeDelegate( object.delegate )
end

在bind方法中,holderDelegate是我们要实现拓展的delegate,我们将组件的Env传给了包的Env,这样,我在包中就可以直接用Env作为包的环境变量了。有一点需要注意的是,由于getfenv的特性,在我们需要使用Env时,必须是在onload之后,也就是说,在包解包后初始化的这个过程,我们没法使用Env,这也是改组件需要优化的地方。

你可能感兴趣的:(lua,环境变量)