无法通过深层链接获取在durandal中触发的停用功能

时间:2013-07-05 12:41:03

标签: durandal

我是durandal和单页应用程序的新手,我在解决停用和canDeactivate功能时遇到问题。我正在使用一些自定义代码来实现深层链接,这可能是导致我的问题的原因。 我按照这里的例子:https://github.com/evanlarsen/DurandalDeepLinkingExample 另请参阅Durandal Subrouting (Hottowel)

非常感谢任何帮助。

这是我正在调用的viewmodel代码:

define([''], function () {

var vm = {
    activate: function () {
        alert('In activate!');
    },
    deactivate: function () {
        alert('In deactivate!');
    },
    canDeactivate: function () {
        alert('In candeactivate!');
    }
}
return vm;

});

这是viewhtml

<div class="container-fixed"> 
 <div>
    <header>
        <!-- ko compose: {view: 'Main/Users/UsersNav'} -->
        <!-- /ko-->
    </header>
    <section id="content" class="in-users">
        <!--ko compose: { 
                            model: inUsers, afterCompose: router.afterCompose,
                            transition: 'entrance', 
                            activate: true
                        } -->
        <!--/ko-->
    </section> 
 </div>
</div>

这是调用代码:

define(['durandal/system', 'durandal/viewModel', 'durandal/plugins/router'],
function (system, viewModel, router) {
    var App = {
        router: router,
        activate: activate,
        showPage: showPage,
        isPageActive: isPageActive,
        inUsers: viewModel.activator(),
    };
    return App;

    var defaultPage = '';
    function activate(activationData) {

        defaultPage = 'ManageUsers';
        App.inUsers(convertSplatToModuleId(activationData.splat));

        router.activeItem.settings.areSameItem = function (currentItem, newItem, data) {
            if (currentItem != newItem) {
                return false;
            }
            else {
                App.inUsers(convertSplatToModuleId(data.splat));
                return true;
            }
        };
    }

    function showPage(name) {
        return function () {
            router.activate('#/Users/' + name);
            //router.navigateTo('#/Users/' + name);
            App.inUsers(convertNameToModuleId(name));
        };
    }

    function isPageActive(name) {
        var moduleName = convertNameToModuleId(name);
        return ko.computed(function () {
            return App.inUsers() === moduleName;
        });
    }

    // Internal methods
    function convertNameToModuleId(name) {
        return 'Main/Users/' + name + '/' + name;
    }

    function convertSplatToModuleId(splat) {
        if (splat && splat.length > 0) {
            return convertNameToModuleId(splat[0]);
        }
        return convertNameToModuleId(defaultPage);
    }
});

编辑:(主页面)

 function activate() {

        // my convention
        router.autoConvertRouteToModuleId = function (url) {
            return 'Main/' + url + '/index';
        };

        return router.activate('Home'); 
    }

Nav HTML for master:
<div class="btn-group">
                     <a href="#/home" class="btn btn-info">HOME</a>
                     <a href="#/resources" class="btn btn-info">RESOURCES</a>  
                     <a href="#/users" class="btn btn-info">USERS</a>               
 </div>    


Main master: 
  <div class="container-fixed"> 
   <div>
    <header>
        <!-- ko compose: {view: 'Main/masterNav'} -->
        <!-- /ko-->
    </header>
    <section id="content" class="main">
        <!--ko compose: {model: router.activeItem, 
            afterCompose: router.afterCompose,
            transition: 'entrance'} -->
        <!--/ko-->
    </section>        
    <footer>
        <!--ko compose: {view: 'Main/masterFooter'} --><!--/ko-->
    </footer>
  </div>
 </div>   

1 个答案:

答案 0 :(得分:2)

您遇到的关于无法停用子路由视图的问题是因为从该方法返回的viewmodel.activator() observable强制执行durandal中的activator pattern。那个observable期待一个amd模块,而不是一个字符串。

即使字符串工作正常,因为compose绑定知道如何根据字符串加载模块.. viewmodel激活器不知道如何从字符串加载模块。

因此,您需要将实际模块传递给observable。

我之前创建的示例只是使用了一个字符串,因此它将组成视图..但如果只有一个字符串,激活器模式就不起作用。因此,您必须将require所有子路径amd模块放入您的调用代码中,然后再使用 convertSplatToModuleId方法..创建一个返回正确模块的新方法。

所以,像这样:

define(['durandal/system', 'durandal/viewModel', 'durandal/plugins/router'],
function (system, viewModel, router) {
    var App = {
        router: router,
        activate: activate,
        showPage: showPage,
        isPageActive: isPageActive,
        inUsers: viewModel.activator(),
    };
    return App;

    var defaultPage = '';
    function activate(activationData) {

        defaultPage = 'ManageUsers';
        convertSplatToModuleId(activationData.splat).then(function(activeModule){
            App.inUsers(activeModule);
        })


        router.activeItem.settings.areSameItem = function (currentItem, newItem, data) {
            if (currentItem != newItem) {
                return false;
            }
            else {
                convertSplatToModuleId(data.splat).then(function (module) {
                    App.inUsers(module);
                });
                return true;
            }
        };
    }

    function showPage(name) {
        return function () {
            router.activate('#/Users/' + name);
            //router.navigateTo('#/Users/' + name);
            convertNameToModuleId(name).then(function(module){
                App.inUsers(module);
            });            
        };
    }

    // Internal methods
    function convertNameToModuleId(name) {
        return system.acquire('Main/Users/' + name + '/' + name);
    }

    function convertSplatToModuleId(splat) {
        if (splat && splat.length > 0) {
            return convertNameToModuleId(splat[0]);
        }
        return convertNameToModuleId(defaultPage);
    }
});