AngularJS - Передача значений из backend в frontend
Какой лучший способ передать значение из бэкэнда в AngularJS в интерфейсе? Я использую Django, и шаблоны могут выплеснуть нужные мне значения, однако я не уверен, что наилучшая практика передачи этих значений в AngularJS.
Подумайте о сообщении в блоге и его комментариях. Если бы у меня была служба AngularJS, которая извлекает все комментарии определенного сообщения в блоге, передавая идентификатор сообщения службе, а Django отображает HTML-шаблон, и он знает, что post ID, однако мне нужно передать этот идентификатор сообщения в AngularJS и впоследствии в службу.
Одна идея состоит в том, чтобы иметь его в скрытом <input>
и назначить этот ввод модели. Не очень привлекательно.
Другой - иметь директиву и передать это значение в атрибуте этой директивы, таким образом, я смог бы получить доступ к этому значению атрибута:
// Django (or any backend) is rendering {{ object.value }}
<div class="myDirective" data-object-id={{ object.value }}>
...
</div>
angular.module('myDirectives', []).
directive('myDirective', function() {
return {
restrict: 'C',
transclude: false,
link: function postLink($scope, $element, $attrs) {
// $attrs.objectId would have the value
}
}
});
Эти два подхода выглядят прекрасно. Но мне интересно, есть ли более чистый способ сделать это? Любой подход, который следует за лучшими методами AngularJS?
Ответы
Ответ 1
Если вам нужно инициализировать только несколько значений модели из представления, директива ng-init
может быть тем, что вы ищете: http://docs.angularjs.org/api/ng.directive:ngInit
Используя его, вы можете просто написать:
<div ng-init="myModel=backend-generated-value-here">
...
</div>
Сказав вышеизложенное, у вас может быть много времени, чтобы найти лучшие практики для вашего прецедента, поскольку AngularJS ориентирован на веб-приложения Web2.0, полностью клиентские. В настоящий момент он идеально не воспроизводится с сервером, создающим контент. Это может измениться в будущих версиях AngularJS.
Ответ 2
Если вам нужно только установить начальные значения для данной "страницы" (что означает обратный вызов для представления), вы можете сделать это, как вы продемонстрировали. Я бы сделал это "чище", установив глобальную переменную с помощью javascript, например:
// Django (or any backend) is rendering {{ object.value }}
<script>
var backendVars = {
{{object.name}} : {{object.value}}
//and any other objects, manually parsed
}
</script>
И прочитайте его с помощью angular в процессе начальной загрузки.
Однако, angularJS является его MVC, поэтому вы можете захотеть установить/получить процессы обработки данных или бэкэнд-контроллеров, не перегружая всю страницу. "Самый чистый" способ заключается в том, чтобы сделать веб-службу для возврата необходимых вам данных (например, представление, которое возвращает JSON, например) и получить его через службу $http или $resource:
angular.module('myApp', []).
controller('MainCtrl', function($scope, $html) {
$html({
method: 'GET',
url: '/your/JSON/view.json'
}).
success(function(data, status){
$scope.yourData = data;
}).
error(function(data, status){
//whatever you need to do if the data is not available
});
}
Кроме того, я должен отметить, что вы не должны поместить данные и логику непосредственно в директивы - они предназначены для манипуляций с DOM - вместо этого получите информацию о контроллере, а затем передайте ее директиве через наследование, атрибуты или 2-сторонняя привязка данных. Надеюсь, что это поможет.
Ответ 3
Я считаю, что правильный способ сделать это - сервер для рендеринга script с помощью поставщика значений, а затем -зависимость-вставить его в вашем приложении. Например:
index.php:
<html ng-app='myApp'>
<head>
<title>AngularJS Back to Front</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<script src='index.js'></script>
<?php
$globals = array(
'count' => 1,
'title' => 'Active users',
'users' => array(
'name' => 'john',
'age' => 21
)
);
$globalsJSON = json_encode( $globals )
?>
<script>
myApp.value('globals', <?=$globalsJSON;?>);
</script>
</head>
<body ng-controller="myController">
<div>{{title}}</div>
</body>
</html>
index.js:
var myApp = angular.module( 'myApp', [] );
myApp.controller( 'myController', [ 'globals', '$scope', function( globals, $scope ) {
// Copy globals to scope
for ( var property in globals ) {
$scope[ property ] = globals[ property ];
}
}]);