Главная / Веб-программирование / Веб-программирование Создание движка для форума с помощью Meteor и AngularJS

Веб-программирование Создание движка для форума с помощью Meteor и AngularJS

Меня часто просят создать небольшие HTML форумы для посетителей сайта и службы поддержки. Поэтому я решил рассказать о том, как это сделать с помощью Meteor и AngularJS:

Создание движка для форума с помощью Meteor и AngularJS

Для начала установим Meteor! Откройте командную строку и вставьте следующую команду:

$ curl https://install.meteor.com/ | sh

Если же вы используете Windows, загрузите официальную программу установки Meteor.

Теперь создадим новое приложение Meteor.

$ meteor create forum

Откройте каталог forum и удалите автоматически сгенерированные файлы: forum.css, forum.html и forum.js.

$ cd forum
$ rm forum.css forum.html forum.js

Я хочу установить Angular-Meteor, удалив ненужные пакеты — blaze-html-templates, ecmascript, autopublish и insecure. Начиная с Meteor v1.2, нужно вручную добавить check, чтобы выполнить базовую санитизацию ввода:

$ meteor remove blaze-html-templates ecmascript autopublish insecure
$ meteor add angular check

Создадим каталоги client и views в корне проекта. Первый представляет собой специальный каталог Meteor, который содержит код, используемый только на стороне клиента. Хотя Meteor позволяет написать код, выполняемый как на стороне клиента, так и на стороне сервера. Это довольно хорошая идея отделить бизнес-логику по соображениям безопасности. Давайте поместим HTML-шаблоны для верстки страниц и каталогов AngularJS в папку views:

$ mkdir client
$ mkdir views

Продолжим реализацию форума для сайта HTML. Создайте файл index.html в корневом каталоге проекта и разместите приведенный ниже код внутри него:

<head>
<title>Angular-Meteor Forum</title>
</head>
<body ng-app="forum">
<div ng-include="’views/forum.html’"></div>
</body>

Это будет загрузочный модуль forum AngularJS, который еще не существует. Он включает в себя шаблон views/forum.htm, который также еще не существует. Давайте исправим это.

Для начала исправим модуль AngularJS. Создайте файл client/app.js и определите модуль:

angular.module(‘forum’, [‘angular-meteor’]);

Далее создайте шаблон форума views/forum.html. Это будет общий макет, используемый всеми страницами:

<div class="forum">
FORUM
</div>

На этом этапе можно запустить приложение.

$ meteor

Откройте браузер и перейдите по адресу http://localhost:3000. Вы должны увидеть текст FORUM. Давайте создадим шаблон views/pages/topics.html для отображения тем HTML форума:

<div class="page">
<h1>Topics</h1>
<div ng-repeat="topic in topics">
<a ui-sref="topic({topicId: topic._id})">{{ topic.name }}</a>
</div>
</div>

Чтобы увидеть этот шаблон в действии, мы установим решение для маршрутизации в AngularJS — angular-ui-router, и определим основные маршруты. Выйдите из Meteor с помощью Ctrl+C или вновь откройте командную строку и перейдите к корневой папке приложения:

meteor add angularui:angular-ui-router

Созданный нами app.js — отличное место для настройки маршрутизации и контроллеров. Тем не менее, вы можете поместить их в разные файлы. Если сделаете это, то убедитесь, что Meteor загружает файлы. Поместите определение модуля в файл client/lib/, иначе он будет загружен после контроллера и каталога, вызывая исключение в AngularJS.

Замените содержимое файла app.js:

angular.module(‘forum’, [‘angular-meteor’, ‘ui.router’])
.config(function($urlRouterProvider, $stateProvider){

// Установка маршрута по умолчанию
$urlRouterProvider
.when(‘/’, ‘/topics’)
.otherwise(‘/topics’);

// Добавление состояния
$stateProvider.state(‘topics’, {
url: ‘/topics’,
templateUrl: ‘views/pages/topics.html’
});

})
.run(function($state){
// Мы вводим $state здесь, чтобы инициализировать ui.router
})

Прежде чем список тем отобразится в браузере, нужно доработать файл views/forum.html. Нам необходим элемент с атрибутом ui-view для отрисовки шаблона форума HTML, связанного с текущим маршрутом:

<div class="forum">
<div class="page-container" ui-view>
</div>
</div>

Перейдите сейчас по адресу http://localhost:3000 и обратите внимание, что вы мгновенно перенаправляетесь на страницу тем. Но у нас еще нет тем. Поскольку мы захотим добавить или удалить темы, будет хорошей идеей сохранить их в базе данных.

Meteor использует СУБД MongoDB. Можно определить коллекции MongoDB с помощью new Meteor.Collection (collectionName). Этот код должен присутствовать и на стороне клиента, и на стороне сервера, поэтому создадим каталог common и поместим данную строку в common/db.js:

Topics = new Meteor.Collection(‘Topics’);

В Meteor публикация — это способ построения набора данных для отправки клиенту. Вы вызываете Meteor.publish с именем набора данных, и функция обратного вызова возвращает курсор в mongodb. Meteor считывает изменения из mongodb oplog (или опрашивает базу данных, если oplog не установлен должным образом) и обновляет курсор, когда данные добавлены, удалены или изменены.

Публикация должна быть определена в файле только для сервера, поэтому создадим папку server. Каждый JavaScript-файл, который вы помещаете сюда, будет работать только на сервере.

Создадим файл server/publications.js:

Meteor.publish(‘topics’, function(){
return Topics.find();
});

Meteor.publish(‘topic’, function(id){
check(id, String);
return Topics.find({_id: id});
});

Это позволит определить две публикации в форуме для сайта HTML: одну для всех тем и одну для той, которую запрашивает идентификатор. Кроме этого, давайте вставим некоторые темы по умолчанию, если коллекция пуста. Поместите приведенный ниже код в server/defaults.js:

if (Topics.find().count() === 0) {
_.each([‘General Discussion’, ‘Tutorials’, ‘Help’], function(topicName){
Topics.insert({name: topicName});
});
}

Клиент инициирует подписку, которая подключается к публикации, и получает эти данные. Давайте посмотрим, как это сделать с помощью Angular-Meteor. В client/app.js добавьте параметр контроллера в определение состояния topics, называемого TopicsContoller, и определите контроллер после .run():

// …
$stateProvider.state(‘topics’, {
url: ‘/topics’,
templateUrl: ‘views/pages/topics.html’,
controller: ‘TopicsContoller’
});
// …
.controller(‘TopicsContoller’, function($scope){
$scope.subscribe(‘topics’);
$scope.helpers({
topics: function() {
return Topics.find({}, {sort: {name:1}});
}
});
})

Здесь мы присоединились к публикации topics, а также добавили помощника с именем topics, который возвращает курсор MongoDB на список тем, отсортированных по именам. С точки зрения AngularJS это простой массив, доступный в переменной $scope.topics.

Просмотрите HTML форум в браузере. Вы должны увидеть три темы в соответствии с заголовком. Тем не менее, если кликнуть по ним, ничего не произойдет. Это потому, что мы не определили состояние topic. Давайте сделаем это и определим TopicController:

// …
$stateProvider.state(‘topic’, {
url: ‘/topic/:topicId’,
templateUrl: ‘views/pages/topic.html’,
controller: ‘TopicContoller’
});
// …
.controller(‘TopicContoller’, function($scope, $stateParams){
$scope.subscribe(‘topic’, function(){ return [$stateParams.topicId]; });
$scope.helpers({
topic: function() {
return Topics.findOne({_id: $stateParams.topicId});
}
});
})

Это довольно просто, но учтите, что нужно использовать функцию, чтобы передать аргумент идентификатора topics публикации и вернуть одну тему с findOne вместо find.

Шаблон views/pages/topic.html будет довольно простым, но не волнуйтесь, мы скоро добавим список ветвей обсуждения:

<div class="page">
<h1>{{ topic.name }}</h1>
</div>

Чтобы использовать HTML код форума для сайта, нужно идентифицировать пользователей. У Meteor есть полезные пакеты для аутентификации:

  • accounts-base: Этот пакет реализует основные функции, необходимые для учетных записей пользователей и позволяет другим пакетам использовать службы входа в систему;
  • accounts-password: служба, которая включает безопасный, основанный на пароле, вход в систему;
  • dotansimha:accounts-ui-angular: AngularJS «контейнер» для пакета UI учетной записи Meteor.

Давайте установим их:

$ meteor add accounts-base accounts-password dotansimha:accounts-ui-angular

Для использования dotansimha:accounts-ui-angular модуль AngularJS должен указать accounts.ui в качестве зависимости:

angular.module(‘forum’, [‘angular-meteor’, ‘ui.router’, ‘accounts.ui’])

Теперь можно добавить аутентификацию, регистрацию, функции: forgot password и change password с помощью одной строки. Лучше всего прописать все это в views/forum.html, поскольку это корневое расположение для всех страниц шаблона форума HTML:

<div class="forum">
<login-buttons></login-buttons>
<div ui-view>
</div>
</div>

Пора создать потоки выполнения:

  • Определить коллекцию common/db.js:

Threads = new Meteor.Collection(‘Threads’);

  • Опубликовать треды (ветви обсуждения) в server/publications.js:

Meteor.publish(‘threads’, function(topicId){
check(topicId, String);
return Threads.find({topicId: topicId});
});

Meteor.publish(‘thread’, function(id){
check(id, String);
return Threads.find({_id: id});
});

  • Отредактировать views/pages/topic.html, чтобы перечислить треды темы и добавить форму, где пользователи могут создавать новые ветви обсуждения:

<div class="page">
<h1>{{ topic.name }}</h1>
<ul>
<li ng-repeat="thread in threads">
<a ui-sref="thread({threadId: thread._id})">{{ thread.content }}</a>
by {{ thread.author }} at {{ thread.createdAt | date }}
</li>
</ul>

<h2>Create a new thread</h2>
<form ng-submit="createThread(thread)">
<input type="text" placeholder="Start discussion…" ng-model="thread.content">
<button type="submit">Create</button>
</form>
</div>

  • Изменить TopicController в client/app.js так, чтобы он подписался к списку тредов, которые принадлежат текущей теме, и управлял созданием ветвей обсуждения:

.controller(‘TopicContoller’, function($scope, $stateParams, $meteor){
$scope.subscribe(‘topic’, function(){ return [$stateParams.topicId]; });
$scope.subscribe(‘threads’, function(){ return [$stateParams.topicId]; });
$scope.helpers({
topic: function() {
return Topics.findOne({_id: $stateParams.topicId});
},
threads: function() {
return Threads.find({topicId: $stateParams.topicId});
}
});
$scope.createThread = function(thread){
$meteor.call("createThread", $stateParams.topicId, thread.content).then(function(){
thread.content = »;
}).catch(function(){
alert("An error occured while creating the thread!");
});
};
})

Увидели вложенную службу $meteor? Мы используем ее для вызова серверного метода createThread, который еще предстоит создать.

Вставьте приведенный ниже код в файл HTML форума server/methods.js:

Meteor.methods({
createThread: function(topicId, content){
check(topicId, String);
check(content, String);
var user = Meteor.user();
if (!user) {
throw new Meteor.Error("You are not logged in!");
}
if (!content){
throw new Meteor.Error("Content is required!");
}
var thread = {
author: user.emails[0].address,
createdAt: new Date(),
topicId: topicId,
content: content
};
return Threads.insert(thread);
}
});

Meteor.methods ожидает объект, в котором ключи — имена методов, а значения — определения методов. Методы могут иметь аргументы и могут возвратить что-либо, что может быть сериализовано в формате JSON. Курсоры Meteor не сериализуются, поэтому постарайтесь избежать возвращения collection.find(…), поскольку это приведет к краху приложения.

Давайте подведем итоги. Мы можем:

  • Перечислить темы;
  • Открыть темы со списком тредов;
  • Создать треды;
  • Зарегистрироваться / войти / выйти, сбросить забытый пароль и изменить пароль.

Что осталось сделать:

  • Определить коллекцию Posts и опубликовать ее так же, как это сделали с Threads;
  • Создать маршрут для одной темы, чтобы перечислить сообщения так же, как это сделали с topic;
  • Создать форму, чтобы публиковать тему, как это сделали с topic;
  • Написать метод для создания записи, как мы это сделали с createThread.

Вы готовы к реализации проекта? Не волнуйтесь, вы всегда можете посмотреть пример создания форума на сайте HTML в репозитории GitHub.

Перевод статьи “Create a Forum Engine in 15 minutes using Meteor & AngularJS” был подготовлен дружной командой проекта Сайтостроение от А до Я.

О нас seoexpert

продвижение сайта,seo оптимизация,поисковое продвижение,раскрутка сайтов,поисковая оптимизация,продвижение сайта в гугл,seo раскрутка,продвижение сайтов в яндексе,продвижение сайта в google,продвижение сайтов в топ 10,Оптимизация и продвижение сайтов,услуги продвижения сайта,заказать продвижение,продвижение сайтов в топ,сео раскрутка сайта

Смотрите также

Определение типа данных double в C, C++ и C#

Double – 64-разрядная переменная с плавающей запятой Тип double — это основной тип данных, который ...