使用自定义指令/操作时路由匹配的控制顺序

Posted

技术标签:

【中文标题】使用自定义指令/操作时路由匹配的控制顺序【英文标题】:control order that routes are matched when using a custom directive/action 【发布时间】:2022-01-17 08:39:31 【问题描述】:

我有一个包罗万象的路由,它在我调用 add_route 之前在使用自定义指令创建的操作中捕获我的请求。我怎样才能防止这种情况发生? IE。手动将包罗万象的路由放在路由匹配过程的末尾,还是将我的操作的 add_route 放在路由匹配过程的前面?

我尝试在admin/routes.pyroutes.py 之间交换includes 的顺序,但这似乎没有影响。一个快速的解决方案(现在考虑它可能是个好主意)是从包罗万象的模式中过滤管理员。但我觉得这会再次出现,我无法做到这一点,所以我问这个问题。

__init__.py

def main(global_config, **settings):
    #...
    config.include('.directives')
    #...
    config.include(".routes")
    #...
    for k in (".customer", ".admin"):
        config.scan(k) # this picks up the admin/admin_routes.py

    return config.make_wsgi_app()   

admin/routes.py

def includeme(config):
    config.add_dispatched_route(
        "admin-plants-edit",
        "/admin/plants/id",
        'plant',
    )

routes.py


def includeme(config):
    #...
    config.add_route("page-view", "/*url")

directives.py


from pyramid.config import PHASE0_CONFIG
from pyramid.httpexceptions import HTTPNotFound

def includeme(config):
    def add_dispatched_route(config, route_name, route_pattern, dispatch_with):
        def route_factory(request):
            api = request.find_service(name=dispatch_with)
            obj = api.by_id(request.matchdict["id"])
            if not obj:
                raise HTTPNotFound()
            return obj
        def route_pregenerator(request, elements, kw):
            api = request.find_service(name=dispatch_with)
            try:
                obj = kw.pop(api.get_pregenerator_kw())
            except KeyError:
                pass
            else:
                kw["id"] = obj.id
            return elements, kw
        def register():
            config.add_route(route_name, route_pattern, factory=route_factory, pregenerator=route_pregenerator)
        config.action(('dispatched_route', route_name), register, order=PHASE0_CONFIG)

    config.add_directive('add_dispatched_route', add_dispatched_route)

【问题讨论】:

包罗万象的路线应该是最后声明的路线。尝试将其移到 for k in (".customer", ".admin"): 块之后。您可能需要将 routes.py 拆分为两个文件,一个在开头包含所有文件,另一个在末尾包含 catchall.py @StevePiercy 我喜欢明确的包罗万象文件的想法,所以我尝试了它,但它似乎不起作用。似乎该操作在所有其他 add_route 调用发生之后注册 add_route ,即使对指令的调用发生在包含 catchall 文件之前。这是一种边缘情况,因为包罗万象的情况非常罕见。我无法控制动作的顺序,因为我本质上是通过调用 add_route 来调用另一个动作。我将只实现一个非框架解决方案。 【参考方案1】:

阶段在 Pyramid 中的工作方式不允许您对阶段内的操作重新排序。基本上想象每次对config.add_route 的调用都被附加到一个列表中,然后迭代该列表以添加路由。您不能在另一个调用之前注入对 config.add_route 的调用。

但是,如果您将每次对 add_route 的调用都包含在自己的操作中,那么您就有机会推迟所有内容、订购东西,然后按照您希望的顺序对每个路由调用 config.add_route

【讨论】:

我最终只是按照您的建议将所有内容包装在我自己的 add_route 中,并且有效。

以上是关于使用自定义指令/操作时路由匹配的控制顺序的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS之基础-5 路由(定义路由使用路由)自定义指令(Directive)

vue 自定义指令及动态指令参数

Vue自定义指令 directive

AngularJs自定义指令详解 - link

自定义指令

Vue.js---自定义指令