如何在带ng-if的Angular条件div中正确更新Razor变量
嘿,我懂你想实现的逻辑,但这里有个核心的执行顺序矛盾得先掰明白:
Razor是服务器端渲染技术,所有@{ ... }里的代码都会在服务器生成HTML页面的时候一次性执行完毕,然后才把完整的HTML发送到浏览器;而Angular的ng-if是客户端指令,只有当页面加载到浏览器后,Angular才会根据条件决定是否显示对应的div。
这就意味着你写的那些在ng-if div里的@{db = "...";}赋值代码,不管vm.IsLoggedIn或者vm.HasAuthorizedUser是什么值,服务器都会全部执行一遍,最后db变量自然会被最后一次赋值(也就是Test3)覆盖,完全无视客户端的ng-if条件。
符合你需求的变通方案
既然你希望保留这种“根据登录/授权状态切换变量值,再传给分部视图”的逻辑,那得把判断逻辑移到服务器端,和客户端的ng-if条件保持一致:
假设你的vm.IsLoggedIn和vm.HasAuthorizedUser这两个状态,是服务器端先传递给Angular的(比如通过Model、ViewBag或者直接注入到Angular的vm里),那服务器端其实可以直接拿到这些状态值,提前完成变量赋值:
@{ var db = "Test1"; // 用服务器端对应的状态变量来判断,比如Model.IsLoggedIn或者ViewBag.IsLoggedIn if (Model.IsLoggedIn) { db = "Test2"; } // 注意:如果两个条件都满足,这里还是会被Test3覆盖,和你原来的逻辑一致 if (Model.HasAuthorizedUser) { db = "Test3"; } } <!-- 客户端的ng-if依然保留,控制div显示 --> <div ng-if="vm.IsLoggedIn">...</div> <div ng-if="vm.HasAuthorizedUser">...</div> <!-- 之后正常把db传入分部视图 --> @{ Html.RenderPartial("_YourPartialView", new ViewDataDictionary { { "DbValue", db } }); }
这样一来,服务器端的赋值逻辑和客户端的显示逻辑完全匹配,既实现了你想要的变量切换效果,也避免了原来的执行顺序问题。
关键提醒
永远记住:Razor和Angular是在两个完全不同的阶段运行的,服务器端代码先跑完,客户端代码才开始执行,你没法用客户端的条件去控制服务器端代码的执行流程——这是前后端分离渲染的核心逻辑,绕不开的哦。
内容的提问来源于stack exchange,提问作者Viplock

