Использование логики между фабриками и контроллерами в Angular.js
Вот описание того, что я пытаюсь сделать:
У меня сейчас есть angular.module
в своем веб-приложении, которое я создаю, это калькулятор цен, в котором пользователи смогут указать, сколько дней / недель они хотели бы прожить в отеле, и чтобы модуль вычислял их расчетную цену с учетом сборов / дней / недель для даты, которые они хотели бы остаться.
В настоящее время у меня есть меню выбора сезонов, потянув от моего angular.factory
через controller
(увидеть ниже). Пользователь может выбрать из различных опций, которые я сохранил на фабрике в качестве литералов объекта, и в зависимости от "метки", которую он выбрал в меню, он рассчитает их цену на основе 1 недели пребывания в этом отеле. Отлично.
Теперь я хотел бы добавить некоторые функциональные возможности для своих степперов, которые я настроил с помощью директивы [Revolunet/angular-stepper][1], которую я решил использовать в качестве своего степпера для каждого дня и недели.
Проблема, с которой я сталкиваюсь, заключается в том, что я не уверен, где делать свою логику для расчетов. Я хотел бы, чтобы пользователь мог выбрать сезон в меню выбора, а затем использовать шагер, чтобы добавить любые дополнительные дни / недели, используя шагер, и динамически корректировать приблизительный итог на основе количества дней / недель, которые выбрал пользователь.,
Я знаю, что у меня не может быть, чтобы диспетчеры говорили друг с другом, и я не могу иметь $scope
искать любые глобальные переменные, кроме app.factory
Я настроил? Могу ли я хранить все angular-stepper
вещи на заводе и мой app.controller
унаследовать это?
Итак, в заключение, я хотел бы динамически изменить сумму в долларах для оценщика цен, когда пользователь добавляет дни и недели к своим запросам, используя предоставленный мною степпер, и я застрял в том, где разместить свою логику для этого. Я надеюсь это имеет смысл!
Вот мой код:
HTML:
<div id= "estimator-wrapper" ng-app="priceEstimator">
<h3> Price Estimator</h3>
<h4> (with fees):</h4>
<div ng-controller="weekStepper">
<div ng-controller="seasonSelector">
<h2>{{ seasonsList.value }}</h2>
<p> Select a season:</p>
<select ng-model="seasonsList" ng-options="season as season.label for season in seasons"></select>
</div>
<label>Number of weeks:</label>
<div min="minRating" max="maxRating" ng-model="rating" rn-stepper></div>
<div ng-controller="dayStepper">
<label>Number of days:</label>
<div min="minRating" max="maxRating" ng-model="rating" rn-stepper></div>
</div>
</div>
Вот мой модуль Angular.js:
const app = angular.module('priceEstimator', ['revolunet.stepper']);
app.factory('seasonFactory', () => {
let factory = {};
let seasons = [
{ label:'-', value: '$' + 0},
{ label:'Fall/Winter', value: '$' + Math.floor((2100 + 245) * 1.115) },
{ label: 'Spring', value: '$' + Math.floor((2900 + 245) * 1.115) },
{ label: 'Summer', value: '$' + Math.floor((3995 + 245) * 1.115) }
];
factory.getSeasons = () => {
return seasons;
};
return factory;
});
app.controller("weekStepper",($scope) => {
$scope.rating = 0;
$scope.minRating = 0;
$scope.maxRating = 8;
});
app.controller("dayStepper",($scope) => {
$scope.rating = 0;
$scope.minRating = 0;
$scope.maxRating = 6;
});
app.controller("seasonSelector",($scope, seasonFactory) => {
$scope.Math = Math;
$scope.seasons = seasonFactory.getSeasons();
$scope.seasonsList = $scope.seasons[0];
});
1 ответ
Вы определенно можете заставить свои контроллеры общаться друг с другом и уже иметь отношения родитель-потомок между weekStepper и dayStepper, потому что день вложен в неделю в html.
Вы можете использовать $parent из дневного степпера для общения с контроллером weekStepper или, поскольку они вложены, дочерний контроллер автоматически наследует свойства родителя.
Однако, поскольку вы уже настроили фабрику, просто введите фабрику в каждый контроллер и получите доступ к свойствам оттуда. Фабрики являются синглетонами, поэтому даже если вы внедрите их в каждый контроллер, все эти ссылки будут указывать на один и тот же экземпляр и иметь одинаковые данные.
Исходя из того, что я сказал выше, из-за того, что ваши контроллеры вложены в ваш html, если вы внедрите seasonFactory и в weekStepper и сохраните его в свойстве (скажем, factory factory), тогда $scope.seasonFactory будет доступен во всех контроллерах. Вы можете сохранить данные на фабрике после их извлечения или переместить код, который сохраняет результаты ваших фабричных методов, на самый внешний контроллер и сделать его доступным везде таким образом.
Здесь много замечательных вопросов и ответов, касающихся контроллеров родителей и детей. Это один из самых популярных: AngularJS получает доступ к родительской области из дочернего контроллера
Кроме того, если вы используете версию 1.5 или выше, это отличная возможность начать использовать компоненты.