2015-06-26 5 views
0

Я пытаюсь создать простой блог-сайт с помощью AngularJS. Я только начинаю, так что я думаю, что это не лучший способ сделать это, поэтому любые альтернативные предложения приветствуются.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 и выполнить итерацию, чтобы найти выбранную статью, а затем передать значения свойств обратно в представление?

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

+3

Ваша первая логика контроллера должна быть действительно службой. https://docs.angularjs.org/guide/services –

+0

Возможный дубликат [Передать переменные контроллеру AngularJS, передовая практика?] (http://stackoverflow.com/questions/11703477/pass-variables-to-angularjs-controller -best-practice) –

ответ

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

Спасибо за такой полный ответ! Сегодня вечером мне понравится кодирование –

3

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

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

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

AngularJS Service Passing Data Between Controllers

+0

Спасибо. Я проверю эту ссылку. –

0

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

AngularJS: Service vs provider vs factory

Смежные вопросы