Маршруты могут содержать различное число параметров. В адресной строке браузера эти параметры представляют отдельные сегменты, разделяемые слешами. Например, http://localhost:8080/answer/2/message имеет три отдельных сегмента: answer, 2 и message.
В AngularJS мы можем использовать два способа определения параметров маршрута, которые могут принимать фиксированное, либо произвольное количество параметров.
Используем параметры маршрутов. Для этого изменим код модуля приложения в файле app.js:
var questApp = angular.module('questApp', ["ngRoute"]) .config(function($routeProvider){ $routeProvider.when('/question', { templateUrl:'views/question.html', controller:'QuestionController' }); $routeProvider.when('/answer', { templateUrl:'views/answer.html', controller:'AnswerController' }); $routeProvider.when("/edit/:id", { templateUrl: "views/answer.html", controller:'AnswerController' }); $routeProvider.when("/edit/:id/:data*", { templateUrl: "views/answer.html", controller:'AnswerController' }); $routeProvider.otherwise({redirectTo: '/question'}); });
Итак, здесь определены два новых маршрута: "/edit/:id"
и "/edit/:id/:data*"
. В первом случае маршрут принимает один параметр id, во втором случае
возможна передача произвольного количества параметров вместо плейсхолдера :data*
. Название каждого параметра предваряется знаком двоеточия.
В итоге первый маршрут будет соответствовать строке запроса edit/3, где "3" представляет параметр id. Второй марщрут будет соответствовать
строке запроса с произвольным количеством параметров, где первый параметр также будет id.
Оба маршрута будут обрабатываться контроллером AnswerController и будет использовать представление answer.html. Цель маршрутов - обеспечить редактирование поста с ответом. Поскольку добавление и редактирования во многом идентичны, то мы можем использовать для них одно и то же представление и одну и ту же логику.
Теперь изменим представление question.html, которое выводит вопрос со списком ответов:
<div class="quest"> <h3>{{question.text}}</h3> <p>{{question.author}} </p> <p><i>{{question.date}}</i></p> </div> <h3>Ответы</h3> <div class="answers"> <div ng-repeat="answer in question.answers | orderBy:sortparam" class="answer"> <div class="vote"> <a class="vote-up" ng-click="voteUp(answer)"></a> <span class="rate">{{answer.rate}}</span> <a class="vote-down" ng-click="voteDown(answer)"></a> </div> <b>{{answer.text}}</b> <p>{{answer.author}}</p> <p><i>{{answer.date}}</i></p> <p><a href="#!edit/{{answer.id}}">Изменить</a></p> </div> </div>
В данном случае изменения сведены к добавлению для каждого ответа ссылки на редактирование: <a href="#!edit/{{answer.id}}">Изменить</a>
.
Переход по этой ссылке будет обрабатываться первым маршрутом edit.
Представление answer.html остается без изменений:
<div ng-controller="QuestionController"> <div class="quest"> <h3>{{question.text}}</h3> <p>{{question.author}} </p> <p><i>{{question.date}}</i></p> </div> </div> <div> <form name="answerForm"> <fieldset> <p><label for="answerText">Текст ответа</label> <input id="answerText" ng-model="answer.text" required placeholder="Введите ответ" /></p> <p><label for="answerAuthor">Автор ответа</label> <input id="answerAuthor" ng-model="answer.author" required placeholder="Введите автора" /></p> </fieldset> <button type="submit" ng-click="save(answer, answerForm)">Сохранить</button> </form> </div>
И теперь код контроллера AnswerController:
questApp.controller('AnswerController', function AnswerController($scope, $http, $location, $templateCache, $routeParams){ $scope.answer = null; $scope.$on('$routeChangeStart', function(event, next, current) { if (typeof(current) !== 'undefined'){ $templateCache.remove(next.templateUrl); } }); $scope.$on("$routeChangeSuccess", function () { var id = $routeParams["id"] if(id!=='undefined'){ $http({method:'GET', url:'getAnswer.php', params: {'id':id}}). then(function success(response) { $scope.answer = response.data; }); } }); $scope.save = function (answer, answerForm){ if(answerForm.$valid){ $http.post("postAnswer.php", answer).then(function success(response) { $location.path("question"); }); } }; })
Ключевым моментом тут является использование сервиса $routeParams, с помощью которого можно получить параметры маршрута.
Чтобы отследить переход по данному маршруту устанавливается обработчик для события $routeChangeSuccess
:
$scope.$on("$routeChangeSuccess", function () { var id = $routeParams["id"] if(id!=='undefined'){ $http({method:'GET', url:'getAnswer.php', params: {'id':id}}). then(function success(data) { $scope.answer = data; }); } });
Если параметр $routeParams["id"]
определен, значит мы хотим редактировать ответ, если нет - то собираемся его создать. Далее с
помощью сервиса $http обращаемся к некоторому ресурсу, который должен нам вернуть объект ответа. Затем полученный объект устанавливается в качестве
значения $scope.answer.
Для целей тестирования я создал примитивный скрипт на php getAnswer.php, который берет данные из json-файла и посылает в ответ:
<?php if(isset($_GET['id'])) { $id = $_GET['id']; $string = file_get_contents("question.json"); $json=json_decode($string,true); // в целях упрощения примера допустим, что // порядок элемента соответствует его id $data = $json["question"]["answers"][$id-1]; echo json_encode($data); } else { echo "Введенные данные некорректны"; } ?>
Но опять же в реальности это будет более сложная логика извлечения данных, которая может написана на любой другой платформе для веб-разработки.