3

我需要一些帮助,使我对这个问题的解决方案更加优雅。

应用程序摘要

该应用程序是使用 pushstate 的单页应用程序。登录页面(路径:/)包含文章链接(路径:/article/:articleId)。还有一个创建文章的链接(路径:/create)。单击任一链接时,URL 会更改并且内容会加载到模式中(我使用的是 Bootstrap,但实现相当不相关)。

解决方案

到目前为止,我有(请原谅我盲目编码的错误):

索引.htm

<!doctype html>
<html ng-app="App">
    <head>
        <title>{{page.title}}</title>
    </head>

    <body>
        <section id="articles" ng-controller="HomepageCtrl">
            <ul>
                <li ng-repeat="article in articles">
                    <a href="/article/{{article.id}}">{{article.name}}</a>
                </li>
            </ul>
        </section>

        <!-- markup simplified for example -->
        <modal id="modal">
            <div class="content ng-view></div>
        </modal>
    </body>
</html>

应用程序.js

angular.module('Application', [], ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider.when('/article/:articleId', {
        templateUrl : '/templates/article.htm',
        controller  : 'ArticleCtrl'
    }).when('/create', {
        templateUrl : '/templates/create.html',
        controller  : 'CreateCtrl'
    });

    $locationProvider.html5Mode(true);
}]).controller('HomepageCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
    $rootScope.page = {
        title : 'This is the homepage'
    };

    $scope.articles = [];
    $scope.articles.push({
        id   : 1,
        name : 'Interesting article'
    });
}]).controller('ArticleCtrl', ['$scope', '$rootScope', '$routeParams', function($scope, $rootScope, $routeParams) {
    $('#modal').modal();

    $rootScope.page = {
        title : 'This is article {{article.name}}' /* Not sure if this works! */
    };
}]).controller('CreateCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
    $('#modal').modal();

    $rootScope.page = {
        title : 'This is the article creation form'
    };
}]);

模板省略。

问题

尽管此解决方案有效,但效果并不好。主页内容保留在后台,与模态内容分离,这很好。当路由匹配时,检索模板内容并点击控制器,模式打开显示内容(ng-view)。这也很好。但是,我认为控制器不应该打开模式。

这样做最优雅的方法是什么?将内容路由到具有独特控制器的模式中的概念对应用程序很重要:将添加更多页面,这些页面都需要遵循此约定。还有其他注意事项,例如浏览器后退按钮和关闭模式应该将用户返回到主页,但这些现在不太重要。一旦我了解了该逻辑的位置以及它如何与控制器交互,我就会很高兴。

4

1 回答 1

2

我要试一试,希望答案是你想要的。

任何 DOM 操作(如上面的@meconroy 所说)都不应该在控制器中完成,而应该在指令中完成。您可以通过执行任意数量的操作轻松地在控制器和指令之间进行通信。我不会介绍整个示例,但希望这会让您指出正确的方向。

要创建“模态”指令,您可以执行以下操作:

.directive('myModal', [ // declare any dependencies here
    function() {
        return {
            restrict: 'EA',
            templateUrl: 'path/to/the/modal/template.html',
            replace: true,
            scope: { currArticle: '='},  // create a two-way binding for "$scope.currArticle"
            link: function(scope, elem, attrs){
                elem.modal();  // initialize the modal using jQuery
                scope.$on('open-modal-' + attrs.name, function(e, article){
                    scope.currArticle = article;
                    elem.modal('open'); // or whatever call will open the modal
                });
            }
        };
    }
]);

然后是您的阅读文章模板(位于path/to/the/modal/template.html本示例中):

<modal my-modal name="'read-article'">
    <!-- bind to modal content here -->
    {{currArticle.id}}: {{currArticle.name}}
</modal>

然后你的控制器:

.controller('HomepageCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
    $rootScope.page = {
        title : 'This is the homepage'
    };
    $scope.articles = [];
    $scope.articles.push({
        id   : 1,
        name : 'Interesting article'
    });
    $scope.displayArticle = function(art){
        $scope.$emit('open-modal-read-article', art);
    };
}]);

最后,您的“家”视图:

...
<section id="articles" ng-controller="HomepageCtrl">
    <ul>
        <li ng-repeat="article in articles">
            <a href="" ng-click="displayArticle(article)">{{article.name}}</a>
        </li>
    </ul>
</section>
...

然后您将为“创建”模式重复上述步骤。希望这为您提供了一个起点并根据需要进行修改。如果您需要更多说明,请告诉我。

于 2013-10-17T14:26:48.897 回答