Итак, в предыдущей статье мы создали и соединили компоненты так, чтобы у нас было простое приложение Movie List как для React, так и для Ember. В этой статье мы будем подключать приложения к Firebase. Firebase - это база данных в реальном времени, которую можно относительно легко использовать.
Если вы хотите заглянуть в финальные репозитории, вот они для проектов React и Ember.
Маршруты
Реагировать
В React загрузка данных не связана окончательно с маршрутами. Загрузка данных будет происходить в componentDidMount
методе жизненного цикла компонента React. Этот проект настолько прост, что мы не использовали react-router
для маршрутизации. Если бы мы усложнили проект, мы могли бы, например, использовать отдельный маршрут для добавления фильмов в базу данных.
Ember
Ember ориентирован на маршрутизатор, а это означает, что маршруты являются ключом к созданию приложений. В приложении Ember мы создали маршрут приложения для размещения компонента landing-page
. Небольшой момент, который следует отметить, заключается в том, что вы не должны размещать компоненты, как у нас, в маршруте приложения, а для простоты и демонстрационных целей, которые мы сделали.
С Ember, когда вы генерируете маршруты, они имеют template.hbs
, controller.js
и route.js
. Небольшое примечание: флаг pod сгруппирует маршрут, контроллер и файл шаблона в папке, которая соответствует имени маршрута, а не помещает шаблон в папку шаблонов и помещает маршрут в маршруты. папка. Это более приятный и аккуратный способ организовать код. Помимо генерируемого маршрута, он будет добавлен в файл router.js
, где определены все маршруты:
// app/router.js import Ember from 'ember'; import config from './config/environment'; const Router = Ember.Router.extend({ location: config.locationType, rootURL: config.rootURL }); Router.map(function() { //this.route('home'); }); export default Router;
Маршрут приложения не определен, поскольку он не генерирует определение маршрута в the router.js
. Пока не беспокойтесь о конфигурации, это выходит за рамки данной статьи. По сути, все маршруты будут определены в функции Router.map
.
Модели и контроллеры
В React состояние будет там, где данные находятся (локально или централизованно управляются), а в Ember данные находятся в хранилище, а модели обеспечивают структуру. Контроллеры не поставляются с библиотекой React, но поставляются с фреймворком Ember.
Прежде чем мы продолжим, нам нужно создать модель с именем movie
:
ember generate model movie title:string description:string image:string
Это сгенерирует модель, которая представляет данные фильмов в нашем приложении. Итак, если мы хотим получить данные из модели, мы взаимодействуем с магазином. С response данные приложения живут в состоянии, а не модели.
В файл маршрута вы можете добавить следующий код:
// app/application/route.js import Route from '@ember/routing/route'; export default Route.extend({ model() { return this.store.query('movie', { orderBy: 'title', }); } });
Итак, мы использовали крючок модели и внутри него мы получили доступ к магазину. Ember поставляется с пакетом ember-data
, который представляет собой полноценный уровень сохранения данных для приложений Ember. Я не собираюсь вдаваться в подробное объяснение, поскольку это немного выходит за рамки данной статьи, но это так же просто, как определение модели, а затем использование хранилища для создания / чтения / обновления / удаления (CRUD) операции для этой модели с вашим настроенным источником данных, в нашем случае с базой данных Firebase в реальном времени.
В Ember мы извлекаем наши данные из файла маршрута и обрабатываем действия пользователя с соответствующего контроллера. Итак, давайте сделаем контроллер приложения для обработки при добавлении фильма:
ember generate controller application --pod
В файле controller.js
для маршрута приложения скопируйте и вставьте следующий код:
// app/application/controller.js import Controller from '@ember/controller'; export default Controller.extend({ actions: { addMovie(title, description, image) { const newMovie = this.store.createRecord('movie', { title, description, image }); newMovie.save(); } }, });
Теперь мы определили действия в контроллере маршрута приложения и определили обработчик модели для файла route.js
. По соглашению возвращаемое значение для хука модели доступно как model
в шаблоне маршрута. Теперь мы можем передать это действие и модель компонентам в файле шаблона маршрута приложения:
//app/application/template.hbs {{landing-page add=(action 'addMovie') movies=model }}
И добавьте свойства ниже в component.js
file для landing-page
:
import Component from '@ember/component'; export default Component.extend({ add:null, movies:null });
Есть некоторое сходство между действиями Redux (пакет для управления состоянием в приложениях React), отправляемыми для изменения состояния, и действиями, которые изменяют данные через хранилище и модели. В Ember подобный потоку паттерн называется DDAU - data-down, actions-up.
В шаблоне landing-page
, где мы определили movie-list
и add-movie-form
, теперь мы можем передать данные модели компоненту movie-list
, а действие add
- компоненту add-movie-form
:
// app/components/landing-page/template.hbs {{movie-list-header}} {{movie-list movies=movies }} {{add-movie-form add=add }}
А для файла формы добавления фильма component.js
скопируйте и вставьте следующий код:
// app/components/add-movie-form/component.js import Component from '@ember/component'; export default Component.extend({ tagName: 'form', classNames: ['add-movie-form'], title: null, image: null, description: null, add:null, submit (event) { event.preventDefault(); this.get('add')(this.get('title'), this.get('description'), this.get('image')); this.setProperties({'title': null, 'image': null, 'description': null}); } });
Firebase
Таким образом, в настоящий момент у нас нет данных или серверной части для хранения данных и сохранения данных. Итак, я знаю, что это перебор для простого приложения, но я собираюсь настроить Firebase, чтобы показать вам, насколько он отличается в приложениях Ember и React. Вам нужно будет создать учетную запись Firebase, если у вас ее еще нет. , не волнуйтесь, у него есть бесплатный уровень. Зайдите в консоль, и вы должны увидеть что-то вроде этого:
У меня уже есть movie-list
, созданный для приложения React. Но давайте, создайте новый проект и дайте ему имя. После создания щелкните свой проект, затем щелкните базу данных слева, щелкните базу данных в реальном времени и запустите в тестовом режиме:
Нажмите на страницу обзора и выберите «Добавить firebase в свое веб-приложение»:
Реагировать
С помощью React и настройки Firebase выполните следующую команду, чтобы установить Firebase в проект:
npm install -S firebase
Добавьте следующий код в firebase.js
файл в папке src
, указав свои данные в пустых строках из раздела «Добавить firebase в свое веб-приложение»:
// src/firebase.js import firebase from 'firebase'; const config = { apiKey: '', authDomain: '', databaseURL: '', projectId: '', storageBucket: '', messagingSenderId: '' }; firebase.initializeApp(config); export default firebase;
Ниже показан компонент AddMovieForm
, добавьте следующий код:
// src/components/form/AddMovieForm.js import React, { Component } from 'react'; import './addMovieForm.css'; import firebase from '../../firebase.js'; class AddMovieForm extends Component { constructor(props) { super(props); this.state = { title: '', description:'', image:'' }; this.handleChange = this.handleChange.bind(this); this.onSubmit = this.onSubmit.bind(this); } render() { return ( <form onSubmit={this.onSubmit} className='movie-form'> <input name='title' value={this.state.title} onChange={this.handleChange} placeholder='title..' required /> <input name='description' value={this.state.description} onChange={this.handleChange} placeholder='description..' required /> <input name='image' value={this.state.image} onChange={this.handleChange} placeholder='image..' required /> <button type='submit'>Add Movie</button> </form> ); } handleChange(event) { this.setState({ [event.target.name]: event.target.value }); } onSubmit (event) { event.preventDefault(); const movies = firebase.database().ref('movies'); const movie = { title: this.state.title, description: this.state.description, image: this.state.image }; movies.push(movie); this.setState({ title:'', description:'', image:'' }); } } export default AddMovieForm;
Теперь, если вы добавите фильмы в свою форму и перейдете к базе данных Firebase, вы увидите, что вы ввели в форму. Это значительно отличается от Ember тем, что вы не взаимодействуете с моделями в React, вы взаимодействуете с Firebase, отправляя данные непосредственно в Firebase.
Следующая часть приложения React - отображение данных. Вернитесь к файлу компонента MovieList.js
в приложении реакции, скопируйте и вставьте следующий код:
// src/components/movie-list/MovieList.js
import React, { Component } from 'react';
import './movieList.css';
import MovieListItem from '../movie-list-item/MovieListItem';
import firebase from '../../firebase.js';
class MovieList extends Component {
constructor(props) {
super(props);
this.state = {
movies:[]
};
}
componentDidMount () {
const itemsRef = firebase.database().ref('movies');
itemsRef.on('value', (snapshot) => {
// Due to firebase database storing data in objects with keys
// we need to grab the values from the movies snapshot object,
// hence using Object.values
below.
const movies = Object.values(snapshot.val())
this.setState({
movies
});
});
}
render() {
return (
<div className='movie-list'>
{this.state.movies.map((movie, i) => {
return(
<MovieListItem movie={movie} key={i}/>
)
})}
</div>
);
}
}
export default MovieList;
Глядя на приведенный выше код в методе жизненного цикла componentDidMount
, вы можете увидеть, что это немного сложнее, чем привязка модели к контроллеру приложения в приложении Ember и простое взаимодействие с хранилищем ember-data
. Здесь вам нужно иметь дело с API Firebase и управлять объектом моментального снимка, который предоставляет Firebase. Как мы увидим ниже, в Ember все проще. Это ключевой момент, о котором следует помнить: хотя у Ember довольно много инструментов, большой API и более крутая кривая обучения, существует множество пакетов, которые абстрагируют задачи / взаимодействия.
Ember
В приложении Ember вы должны использовать адаптер, который абстрагирует все взаимодействия с серверами Firebase.
Перво-наперво нам нужно установить адаптер emberfire
. Итак, перейдите в корень вашего проекта Ember и введите в командную строку следующее:
ember install emberfire
Создайте еще один проект на Firebase для приложения Ember и скопируйте объект Firebase, создайте файл firebase.js
в папке config:
// config/firebase.js module.exports = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "" };
Теперь перейдите в папку конфигурации ember, перейдите в файл environment.js
, импортируйте объект Firebase и поместите его, как показано ниже:
'use strict'; const firebase = require('./firebase'); module.exports = function(environment) { var ENV = { modulePrefix: 'movie-list', environment: environment, rootURL: '/', locationType: 'auto', EmberENV: { FEATURES: { // Here you can enable experimental features on an ember canary build // e.g. 'with-controller': true } }, APP: { // Here you can pass flags/options to your application instance // when it is created }, firebase }; if (environment === 'development') { //...
И это так просто. Если вы помните, мы создали действия на контроллере приложения:
// app/application/controller.js import Controller from '@ember/controller'; export default Controller.extend({ actions: { addMovie(title, description, image) { const newMovie = this.store.createRecord('movie', { title, description, image }); newMovie.save(); } }, });
Мы взаимодействуем с хранилищем и находим или удаляем записи, не имея необходимости напрямую взаимодействовать с API firebase или иметь какой-либо код, специфичный для хранения данных в firebase. Поэтому, когда вы добавляете запись в хранилище, она автоматически добавляется в вашу базу данных firebase в коллекцию фильмов.
Какой фреймворк побеждает?
Итак, вы должны иметь четкое представление о различиях после создания обоих этих небольших приложений.
Маршруты являются неотъемлемой частью Ember, и в React меньше внимания уделяется маршрутам и больше - объединению компонентов и их повторному использованию. React, как правило, требует дополнительной настройки, и это обусловлено дизайном библиотеки, существует множество способов настройки проекта, и это обеспечивает невероятную гибкость. В то время как Ember более жесткий и упрямый в том, как вы должны действовать.
В Ember есть ember-data
и модели, ember-data
упрощает взаимодействие с хранилищем и извлечение данных из моделей. React, с другой стороны, имеет локальное состояние, в котором находятся данные, и, если хотите, Redux или flux, два невероятно популярных шаблона управления состоянием.
Итак, что бы я выбрал я? Для меня это не одно и то же. Это все равно, что сравнивать Mac с компьютером с Windows, во многом это зависит от предпочтений и пригодности. Ember - это фреймворк, который спроектирован так, чтобы иметь согласованную архитектуру при масштабировании и усложнении приложений. React имеет меньший API с меньшей встроенной функциональностью и больше полагается на экосистему, когда вы хотите внедрить архитектуру для управления сложными приложениями.
Ключевое отличие состоит в том, что ember может абстрагироваться, например, адаптер firebase абстрагирует все взаимодействия с API firebase. Где, как в React, вы можете усложнить взаимодействие с API или, если хотите, вы можете установить пакеты, которые могут обеспечить более традиционную структуру MVC.
Однако с точки зрения младшего разработчика React намного проще изучить и освоить. Вы можете очень быстро создавать невероятно интерактивные приложения с отличным пользовательским интерфейсом. Ember может создавать такие же хорошие приложения, но у него более крутая кривая обучения и гораздо больше правил для ваших действий. При этом, когда вы понимаете, как работает Ember ... использование адаптеров, надстроек и создание шаблонного кода становится намного проще.
Я обнаружил, что не могу спуститься по одну сторону забора - что вы думаете? Не стесняйтесь добавлять ниже свои комментарии о своем опыте работы с Ember vs React. Было бы здорово услышать об опыте других людей с этими двумя фреймворками.