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)。これもいいですね。ただし、コントローラーがモーダルを開く必要はないと思います。

これを行う最もエレガントな方法は何ですか? 固有のコントローラーを使用してコンテンツをモーダルにルーティングするという概念は、アプリケーションにとって重要です。さらに多くのページが追加され、すべてこの規則に従う必要があります。ブラウザの戻るボタンやモーダルを閉じるとユーザーがホームページに戻るなど、他にも注意事項がありますが、現時点ではそれほど重要ではありません。このロジックを配置する場所と、コントローラーとのインターフェイス方法を理解したら、満足です。

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 に答える