简体   繁体   English

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

[英]How to get angular.js to load content into a modal

I need some help making my solution to this problem more elegant. 我需要一些帮助,使我对这个问题的解决方案更加优雅。

Summary of app 应用摘要

The app is a single-page app using pushstate. 该应用是使用pushstate的单页应用。 The landing page (path: /) contains links to articles (path: /article/:articleId). 登录页面(路径:/)包含文章的链接(路径:/ article /:articleId)。 There is also a link to create an article (path: /create). 还有一个创建文章的链接(路径:/ create)。 When either link is clicked, the URL is changed and the content is loaded into a modal (I'm using Bootstrap but the implementation is fairly irrelevant). 单击任一链接时,URL将更改,内容将加载到模式中(我使用的是Bootstrap,但实现方式相当无关紧要)。

Solution

So far I have (and please excuse errors as I'm coding blind): 到目前为止,我有(并请原谅错误,因为我编码盲):

index.htm 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 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'
    };
}]);

Templates omitted. 模板省略。

Problem 问题

While this solution works, it's not great. 虽然这个解决方案有效但并不好。 The homepage content remains in the background and is separated from the modal content, which is good. 主页内容保留在后台并与模态内容分开,这很好。 When the route is matched, the template content is retrieved and the controller is hit, the modal opens displaying the content (ng-view). 当路线匹配时,检索模板内容并点击控制器,模态打开显示内容(ng-view)。 This is also good. 这也很好。 However, I don't think controllers should be opening modals. 但是,我不认为控制器应该打开模态。

What is the most elegant way of doing this? 这样做最优雅的方式是什么? The concept of routing content into the modal with unique controllers is significant to the application: there will be lots more pages added which will all need to follow this convention. 使用唯一控制器将内容路由到模态的概念对于应用程序来说很重要:将添加更多页面,这些页面都需要遵循此约定。 There are other caveats, eg browser back button and closing the modal should return user to homepage, but these are less significant right now. 还有其他注意事项,例如浏览器后退按钮和关闭模式应该将用户返回到主页,但这些现在不太重要。 Once I understand where to sit this logic and how it interfaces with the controllers I'll be happy. 一旦我理解了这个逻辑的位置以及它与控制器的接口,我就会很高兴。

I'm going to give this a shot, hopefully the answer will be what you're looking for. 我打算给它一个机会,希望答案将是你正在寻找的。

Any DOM manipulation (as @meconroy said above) should not be done in a controller, but should instead be done in a directive. 任何DOM操作(如@meconroy上面所述)都不应该在控制器中完成,而应该在指令中完成。 You can easily communicate between your controller and the directive by doing any number of things. 通过执行任何操作,您可以轻松地在控制器和指令之间进行通信。 I'm not going to go through an entire example, but this will hopefully get you pointed in the right direction. 我不打算通过一个完整的例子,但这有望让你指向正确的方向。

To create a "modal" directive, you would do something like the following: 要创建“模态”指令,您可以执行以下操作:

.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
                });
            }
        };
    }
]);

And then your read-article template (located at path/to/the/modal/template.html for this example): 然后是您的阅读文章模板(位于此示例的path/to/the/modal/template.html ):

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

And then your controller: 然后你的控制器:

.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);
    };
}]);

And finally, your "home" view: 最后,你的“家”观点:

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

And then you would repeat the above steps for the "create" modal. 然后,您将为“创建”模式重复上述步骤。 Hopefully that gives you a place to start from and modify as needed. 希望这能为您提供一个起点并根据需要进行修改的地方。 Let me know if you need more clarification. 如果您需要更多说明,请与我们联系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM