如何获取angular.js将内容加载到模态中

时间:2013-10-17 12:40:52

标签: javascript angularjs modal-dialog twitter-bootstrap-3

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

应用摘要

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

解决方案

到目前为止,我已经(并且请原谅错误,因为我编码失明):

的index.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>

app.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)。这也很好。但是,我认为控制器不应该打开模态。

这样做最优雅的方式是什么?使用唯一控制器将内容路由到模态的概念对于应用程序来说很重要:将添加更多页面,这些页面都需要遵循此约定。还有其他警告,例如浏览器后退按钮和关闭模式应该返回用户到主页,但这些现在不太重要。一旦我理解了这个逻辑的位置以及它与控制器的接口,我就会很高兴。

1 个答案:

答案 0 :(得分:2)

我准备给你一个机会,希望答案是你正在寻找的。

任何DOM操作(如上所述@m.e.conroy)都不应该在控制器中完成,而应该在指令中完成。通过执行任何操作,您可以轻松地在控制器和指令之间进行通信。我不打算通过整个示例,但这有望让你指向正确的方向。

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

.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>
...

然后你会为“创建”模式重复上述步骤。希望这能为您提供一个起点并根据需要进行修改的地方。如果您需要更多说明,请与我们联系。