【发布时间】:2013-11-14 09:23:37
【问题描述】:
我正在使用 Durandal 2.0 构建应用程序。
我的 shell 视图如下所示:
<div>
<header id="nav" data-bind="compose: 'viewmodels/nav', activate: false">
</header>
<section id="content" class="main container-fluid" data-bind="router: { transition: 'entrance' }, activate: false" style="overflow: auto">
</section>
<footer>
<!--ko compose: {view: 'footer'} --><!--/ko-->
</footer>
</div>
在导航部分,我想要我的选项卡和用户的下拉列表(两者都是从 Web 服务中检索的)。从下拉列表中选择用户将导航到将更新内容部分的新 URL。 (路由看起来像 localhost/#user1/tab2)。
- 问题:我需要先从导航部分了解所选用户,然后才能检索内容部分的数据,但内容部分在我检索用户之前已激活。
这实际上只是初始页面加载的问题,因为用户列表只检索一次。
- 有没有办法告诉内容部分等到导航部分完成加载?
- 有没有比我现在做的更好的方法来解决这个问题?
导航激活函数如下所示:
function activate(context) {
return dataservice.getUsers().then(function () {
//do stuff
});
});
首先调用此激活函数,然后调用 dataservice.getUsers(),然后在“做事”部分发生之前调用内容模块的激活函数(并且在 getUsers 调用的数据返回之前)数据服务)。也许我的承诺有问题?
编辑
我已经将 dFiddle 与一些实际代码放在一起,这些代码显示了我在说什么:http://jerrade.github.io/dFiddle-2.0/#test/dashboard
代码在这里:https://github.com/jerrade/dFiddle-2.0
导航.js
function activate(context) {
console.log('Nav View Activated');
if (vm.impersonateUsername == undefined)
vm.impersonateUsername = getUsernameFromWindowLocation();
return dataservice.getPageDetailForEmployee(vm.loggedInUsername, vm).then(function () {
console.log("Page details retrieved");
// I want to do something here before the dashboard activates.
});
}
dashboard.js
function activate(username) {
console.log('Dashboard View Activated');
//vm.username = nav.selectedImpersonateEmployee().Username;
return dataservice.getDashboard(nav.impersonateUsername, dashboard);
}
打开页面并观察控制台。你会看到(除其他外)
Nav View Activated
Dashboard View Activated
Page details retrieved
我真正想要的是在仪表板视图激活之前检索页面详细信息。我实际上已经重新调整了一些事情,以便目前这不再是一个问题,但它可能会再次出现。
看起来我想做的事情不应该这么复杂。除非我在这里用方钉敲打圆孔?
【问题讨论】:
-
不,我认为你的承诺很好...... nav 的
activate方法与内容模块的activate方法无关。有关如何使它们彼此“关联”的建议,请参阅下面的更新答案! -
我已经向你的分叉提交了一个拉取请求。现在的问题是您将 ajax 请求的延迟作为您的 activate 方法返回,该方法会在 ajax 请求返回后立即解决(而不是在您的处理完成后)。我无法测试代码,因为我无法访问您的 API,但我很确定它现在应该可以工作了。
-
我更改了代码以返回延迟,但它仍然在做同样的事情。一旦代码执行 dataservice.getPageDetailForEmployee,它就会切换到仪表板激活。我已经模拟了我的 api 调用,所以如果你愿意,你应该可以在你的机器上运行它。
-
好的;比我想象的要复杂,但下面答案的本质仍然是正确的。在员工加载之前,您必须阻止仪表板的激活。路由器仍将激活仪表板(因为您已经告诉它有关路由的信息),但如果您愿意,您可以使用
if绑定处理程序(答案的第一部分)阻止它绑定。希望更新的拉取请求有所帮助! -
这行得通,谢谢。不过,感觉要添加很多东西。我认为要点是,最好尝试以一种一切都可以异步发生的方式构建事物。
标签: durandal