AngularJS - передать параметры в контроллер?

0

Я пытаюсь создать простой блог-сайт, используя AngularJS. Я только начинаю, так что я думаю, что это не лучший способ сделать это, поэтому любые альтернативные предложения приветствуются.

У меня есть файл controller.js с двумя блочными контроллерами. Один, чтобы отобразить список сообщений в блогах, а другой, который отображает содержимое сообщения, включая HTML файл.

controller.js

myAppControllers.controller('BlogListCtrl', ['$scope', '$http', function ($scope, $http) {
    $http.get('articles/articles.json').success(function (articles) {
        $scope.articles = articles;
    });
}]);

myAppControllers.controller('BlogPostCtrl', ['$scope', '$routeParams', function ($scope, $routeParams) {
    $scope.includeFile = 'articles/' + $routeParams.blogPostId + '.html';
}]);

articles.json

[
{
    "id": "test-article-one",
    "title": "Test Article one",
    "author": "Gareth Lewis",
    "datePosted": "2015-06-23",
    "summary": "This is a test summary"
},
{
    "id": "test-article-two",
    "title": "Test article two",
    "author": "Gareth Lewis",
    "datePosted": "2015-06-23",
    "summary": "This is a test for article two"
}
]

app.js

when('/blog', {
            templateUrl: 'partials/blog-articles.html',
            controller: 'BlogListCtrl'
        }).
        when('/blog/:blogPostId', {
            templateUrl: 'partials/blog-post.html',
            controller: 'BlogPostCtrl'
        }).

блог-post.html

<ng-include src="'partials/header.html'"></ng-include>

<!-- Want to add title, author, datePosted information here... -->

<article class="content">
    <ng-include src="includeFile"></ng-include>
</article>

Эти записи в блогах работают нормально. Когда я нажимаю на сообщение в блоге, он также обслуживает содержимое из файла HTML в порядке. Однако я хочу иметь возможность повторно использовать свойства title, author и datePosted из выбранной статьи в частичном представлении blog-post.html. Какой лучший способ сделать это? Нужно ли мне каким-то образом передать их контроллеру, чтобы перейти к просмотру? Я действительно не хочу передавать их как routeParams. Или мне нужно сделать $ http.get на articles.json и выполнить итерацию, чтобы найти выбранную статью, а затем передать значения свойств обратно в представление?

Спасибо за помощь.

Теги:
model-view-controller

3 ответа

3
Лучший ответ

Вы сказали, что предложения приветствуются, так что вот оно.

1 - транспортировать всю логику вашего блога к сервису;

2 - Предоставить данные по разрешению маршрутов. Это лучший подход для обработки ошибок во время загрузки, 404 и т.д. Вы можете предоставить слушателю $routeChangeError и справиться с ним там;

3 - В службе, объявленной ниже, у вас есть методы для вызова ваших данных и метода для извлечения списка, кэшированного в службе:

// services.js
myAppServices
    .service('BlogService', ['$http', '$q', function ($http, $q) {
        var api = {},
            currentData = {
                list: [],
                article: {}
            };

        api.getSaved = function () {
            return currentData;
        };

        api.listArticles = function () {
            var deferred = $q.defer(),
                backup = angular.copy(currentData.list);

            $http.get('articles/articles.json')
                .then(function (response) {
                    currentData.list = response;

                    deferred.resolve(response);
                }, function () {
                    currentData.list = backup;

                    deferred.reject(reason);
                });

            return deferred.promise;
        };

        api.getArticle = function (id) {
            var deferred = $q.defer(),
                backup = angular.copy(currentData.article),
                path = 'articles/' + id + '.html';

            $http.get(path, {
                cache: true
            })
                .then(function (response) {
                    currentData.article = {
                        path: path,
                        response: response
                    };

                    deferred.resolve(currentData.article);
                }, function (reason) {
                    currentData.article = backup;

                    deferred.reject(currentData.article);
                });

            return deferred.promise;
        };

        return api;
    }]);

BlogService.getSaved() будет извлекать сохраненные данные, сделанные после каждого вызова.

Я также создал метод для вызова пути ng-include, поэтому вы можете проверить, существует ли он, с cache === true, браузер сохранит его копию при повторном вызове в представлении. Также делается копия ответа на статью в блоге, поэтому вы можете получить доступ к ее пути и ответам, когда вам нужно.

На контроллерах, приведенных ниже, они были адаптированы для удовлетворения текущих потребностей:

// controller.js
myAppControllers
    .controller('BlogListCtrl', ['$scope', 'articles',
        function ($scope, articles) {
            $scope.articles = articles;

            /* OTHER STUFF HERE */
        }
    ])
    .controller('BlogPostCtrl', ['$routeParams', '$scope', 'article' 'BlogService',
        function ($routeParams, $scope, article, BlogService) {
            // On 'article' dependency, you have both the original response
            // and the path formed. If you want to use any of it.

            $scope.includeFile = article.path;

            // To get the current stored data (if any):
            $scope.articles = BlogService.getSaved().list;

            // Traverse the array to get your current article:
            $scope.article = $scope.articles.filter(function (item) {
                return item.id === $routeParams.id;
            });

            /* OTHER STUFF HERE */
        }
    ]);

И объявления маршрута были изменены для загрузки данных при разрешении маршрутов.

// app.js
$routeProvider
    .when('/blog', {
        templateUrl: 'partials/blog-articles.html',
        controller: 'BlogListCtrl',
        resolve: {
            articles: ['BlogService', '$routeParams', function (BlogService, $routeParams) {
                return BlogService.listArticles();
            }]
        }
    })
    .when('/blog/:id', {
        templateUrl: 'partials/blog-post.html',
        controller: 'BlogPostCtrl',
        resolve: {
            article: ['BlogService', '$routeParams', function (BlogService, $routeParams) {
                return BlogService.getArticle($routeParams.blogPostId);
            }]
        }
    })
3

Это, возможно, общий вопрос в угловом. Вы должны понимать, что Scope определен для каждого контроллера... Для обмена данными между контроллерами у вас все еще есть возможность использовать $scope.$parent $rootScope или $rootScope для соединения контроллеров, но я бы использовал их внимательно.

Лучше использовать Angular Services, основанные на шаблонах singleton, поэтому вы можете использовать их для обмена информацией между контроллерами, и я думаю, что это будет лучший подход.

Я обнаружил, что это было обсуждено ранее, и вот несколько хороших примеров:

Служба AngularJS, передающая данные между контроллерами

  • 0
    Благодарю. Я проверю эту ссылку.
0

Вы можете использовать глобальную область для установки этих данных, или вы можете использовать службу для обмена данными между контроллерами. Существует много способов решить эту проблему, прочитав немного подробнее об услугах в приведенной ниже ссылке и узнайте, можете ли вы найти решение этой проблемы.

AngularJS: Сервис против поставщика и завода

Ещё вопросы

Сообщество Overcoder
Наверх
Меню