Примечание: Для более современной альтернативы ngReact мы рекомендуем использовать react2angular, angular2react и ngimport.
Библиотека React.js может использоваться как компонент представления в веб-приложениях. NgReact — это модуль Angular, который позволяет использовать компоненты React в приложениях AngularJS.
Мотивация для этого может быть любым из следующего:
Вам требуется большая производительность, чем предлагает Angular (двустороннее привязывание данных, Object.observe, слишком много наблюдателей области на странице), и React обычно более производителен благодаря Виртуальному DOM и другим оптимизациям.
React предлагает более простой способ рассмотреть состояние вашего интерфейса; вместо того чтобы данные передавались обоюдно между контроллером и представлением, как в случае с двусторонним привязыванием данных, React обычно отказывается от этого в пользу более однонаправленной/реактивной парадигмы.
Кто-то из сообщества React выпустил компонент, который вы бы хотели попробовать.- Вы уже глубоко погружены в приложение Angular и не можете его покинуть, но хотите экспериментировать с React.
Установите через Bower:
bower install ngReact
или через npm:
npm install ngreact
Затем просто убедитесь, что Angular, React и ngReact доступны на странице,
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/react/react.js"></script>
<script src="bower_components/react/react-dom.js"></script>
<script src="bower_components/ngReact/ngReact.min.js"></script>
и включите модуль 'react' Angular как зависимость для нового приложения
<script>
angular.module('app', ['react']);
</script>
и вы готовы к работе.
Конкретно, ngReact состоит из:
react-component
, директивы Angular, которая делегирует управление React КомпонентуreactDirective
, сервис для преобразования компонентов React в директиву Angular react-component
. NgReact можно использовать в существующих приложениях на Angular для замены полных или частичных представлений компонентами React.Направление react-component
является универсальным обёртыванием для внедрения ваших компонентов React.
С приложением Angular и объявлением контроллера, таким как это:
angular
.module('app', ['react'])
.controller('helloController', function($scope) {
$scope.person = { fname: 'Clark', lname: 'Kent' };
});
И компонентом React такого типа:
var HelloComponent = React.createClass({
propTypes: {
fname: React.PropTypes.string.isRequired,
lname: React.PropTypes.string.isRequired
},
render: function() {
return (
<span>
Привет {this.props.fname} {this.props.lname}
</span>
);
}
});
app.value('HelloComponent', HelloComponent);
```Компонент может использоваться в представлении Angular с помощью директивы react-component следующим образом:
```html
<body ng-app="app">
<div ng-controller="helloController">
<react-component name="HelloComponent" props="person" watch-depth="reference"/>
</div>
</body>
Здесь:
name
проверяет наличие инжектабельного объекта Angular с этим именем и падает обратно на глобально экспонируемую переменную того же имени;props
указывает, какие свойства области видимости должны быть доступны для компонента React;watch-depth
указывает стратегию отслеживания изменений свойств области видимости. Возможные значения для react-component — reference
, collection
и value
(по умолчанию).Услуга reactDirective, в отличие от директивы react-component, предназначена для создания конкретных директив, соответствующих компонентам React. В фоновом режиме это фактически создаёт и настраивает директивы, специально привязанные к указанному компоненту React.
Если, например, вы хотите использовать тот же компонент React в нескольких местах, вам придётся повторно указывать <react-component name="yourComponent" props="props"></react-component>
, но если вы используете фабрику reactDirective, вы можете создать директиву <your-component></your-component>
и просто использовать её везде.
Услуга принимает компонент React в качестве аргумента.
app.directive('helloComponent', function(reactDirective) {
return reactDirective(HelloComponent);
});
Вместо этого вы можете предоставить имя компонента.```javascript app.directive('helloComponent', function(reactDirective) { return reactDirective('HelloComponent'); });
Это создает директиву, которая может использоваться следующим образом:
```html
<body ng-app="app">
<div ng-controller="helloController">
<hello-component fname="person.fname" lname="person.lname" watch-depth="reference"></hello-component>
</div>
</body>
Служба reactDirective
будет считывать propTypes
компонента React и наблюдать за атрибутами с этими именами. Если ваш компонент React не имеет определенных propTypes
, вы можете передать массив имен атрибутов для наблюдения. Если вы не передаете массив имен атрибутов, в качестве последнего средства будут использоваться атрибуты директивы. По умолчанию атрибуты будут отслеживаться по значению, однако вы также можете выбрать отслеживание по ссылке или коллекции, указав атрибут watch-depth
. Возможные значения — reference
, collection
и value
(по умолчанию).
app.directive('hello', function(reactDirective) {
return reactDirective(HelloComponent, ['fname', 'lname']);
});
Вы также можете настроить глубину отслеживания для каждого свойства/атрибута, обернув имя и объект опций в массив внутри массива свойств:
app.directive('hello', function(reactDirective) {
return reactDirective(HelloComponent, [
'person', // использует глубину отслеживания всей директивы
['place', { watchDepth: 'reference' }],
['things', { watchDepth: 'collection' }],
['ideas', { watchDepth: 'value' }]
]);
});
```По умолчанию ngReact оборачивает любые переданные функции в `scope.$apply`. Вы можете переопределить это поведение, например, если передаёте компонент React как свойство. Это можно сделать явным образом, добавив `wrapApply: false` в конфигурацию свойства:```javascript
app.directive('hello', function(reactDirective) {
return reactDirective(HelloComponent, [
'person',
['place', { watchDepth: 'reference' }],
['func', { watchDepth: 'reference', wrapApply: false }]
]);
});
Если вам нужно изменить конфигурацию созданной директивы службой reactDirective
, например, изменить restrict: 'E'
на restrict: 'C'
, вы можете сделать это, передав объект литерал с желаемой конфигурацией.```javascript
app.directive('hello', function(reactDirective) {
return reactDirective(HelloComponent, undefined, { restrict: 'C' });
});
### Минификация
Многие автоматические библиотеки аннотации, включая ng-annotate, игнорируют неявные аннотации директив. Из-за этого вы можете получить следующую ошибку при использовании директивы в минифицированном коде:
Неизвестный провайдер: eProvider <- e <- helloDirective
Чтобы исправить это, добавьте явную аннотацию зависимости
```javascript
var helloDirective = function(reactDirective) {
return reactDirective('HelloComponent');
};
helloDirective.$inject = ['reactDirective'];
app.directive('hello', helloDirective);
В существующем приложении Angular часто требуется использовать уже существующие сервисы или фильтры из вашего React компонента. Это можно сделать с помощью внедрения зависимостей Angular. React компонент будет всё ещё отображаться как было указано выше, используя директиву react-component.
Также возможно передать Angular injectables и другие переменные как четвёртый параметр прямо в reactDirective
, который затем привяжет их к свойствам.```javascript
app.directive('helloComponent', function(reactDirective, $ngRedux) {
return reactDirective(HelloComponent, undefined, {}, { store: $ngRedux });
});
Обратите внимание, что вы не можете внедрять Angular директивы в JSX.
```javascript
app.filter('hero', function() {
return function(person) {
if (person.fname === 'Clark' && person.lname === 'Kent') {
return 'Superman';
}
return person.fname + ' ' + person.lname;
};
});
/** @jsx React.DOM */
app.factory('HelloComponent', function($filter) {
return React.createClass({
propTypes: {
person: React.PropTypes.object.isRequired
},
render: function() {
return <span>Hello {$filter('hero')(this.props.person)}</span>;
}
});
});
<body ng-app="app">
<div ng-controller="helloController">
<react-component name="HelloComponent" props="person" />
</div>
</body>
При тестировании вы можете запустить JSXTransformer
в браузере. Чтобы это работало с Angular, вам нужно убедиться, что код JSX был преобразован до того, как будет запущено приложение Angular. Для этого можно мануально инициализировать приложение Angular. Для рабочего примера см. пример jsx-transformer.
Примечание: Обходной путь для этого является хаковым, так как загрузка Angular откладывается с помощью setTimeout
. Поэтому рассмотрите возможность преобразования JSX в процессе сборки.
exports-loader
) таким образом, чтобы require('angular')
возвращал правильное значение. Конфигурация модулей вашего Webpack должна содержать следующую конфигурацию загрузчика:```js... module: { rules: [ { test: path.resolve(__dirname, 'node_modules/angular/angular.js'), use: 'exports?window.angular' } ] }, ...
## Разработка
Перед началом разработки выполните:
```bash
npm install
bower install
Создайте минифицированную версию и запустите тесты с помощью:
grunt
Постоянно выполняйте тесты во время разработки с помощью:
grunt karma:background watch
Примеры в папке examples/
используют bower_components
. Для установки этих компонентов сначала установите Bower на вашей машине:
npm install --global bower
Затем установите Bower-компоненты:
bower install
Примеры должны запускаться на локальном веб-сервере, например http-server.
Запустите примеры, запустив веб-сервер в корневой папке проекта.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )