【问题标题】:AngularJS - Passing values from backend to frontendAngularJS - 将值从后端传递到前端
【发布时间】:2012-11-12 13:46:41
【问题描述】:

在前端将值从后端传递到 AngularJS 的最佳方式是什么?我正在使用 Django,模板能够吐出我需要的值,但是我不确定将这些值传递给 AngularJS 的最佳做法是什么。

想想一篇博客文章及其 cmets,如果我有一个 AngularJS 服务,它通过将文章 ID 传递给该服务来检索某个博客文章的所有 cmets,并且 Django 正在呈现 HTML 模板并且它确实知道什么是帖子 ID,但是我需要将此帖子 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 最佳实践的方法?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    如果您只需要从视图中初始化少数模型值,ng-init 指令可能就是您正在寻找的:http://docs.angularjs.org/api/ng.directive:ngInit

    使用它你可以简单地写:

    <div ng-init="myModel=backend-generated-value-here">
       ...
    </div>
    

    如上所述,您可能很难为您的用例找到最佳实践,因为 AngularJS 专注于 Web2.0,全客户端 Web 应用程序。目前,它与服务器端生成内容的播放效果并不理想。它可能会在 AngularJS 的未来版本中发生变化。

    【讨论】:

    • 谢谢。我会说大约 90% 的应用程序已转换为客户端,而后端 (Django) 则纯粹为其余 API 提供服务。
    • 正如文档所说,ng-init 仅适用于 ng-repeat,更好的方法是创建自定义指令以将数据从 html 传递到控制器。
    • 我很好奇 Django 编译器和 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,因此您可能希望能够设置/获取数据或后端控制器的进程,而不必重新加载整个页面。 “最干净”的方法是让 Web 服务返回您需要的数据(例如,返回 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路数据绑定。希望对您有所帮助。

    【讨论】:

    • 我无法调用 Web 服务,因为它取决于后端传递的值。想想博客文章和显示此博客文章的视图,如果我有一个返回此博客文章信息的 API,我需要将文章 ID 传递给 Web 服务以检索其数据。
    • 那么答案的第一部分就是您所要求的。但它不是“棱角分明的”——您正在使用一个大的(并且结构严密的)MVC 框架来完成一个较小的、类似工具带的框架(如 jQuery 或更面向模型的东西)的工作。在 Angular 中,你会这样想:为什么调用 you.com/blog/123 并使用每个不同的页面引导应用程序,当你可以调用 you.com/#/blog/123 并使用 $route 和 $html 来获取博客内容,在更改视图时从不离开页面(应用程序)?同样,如果是用于博客之类的东西,角度可能不是最佳选择。
    • 你说得有道理。我宁愿不污染全局命名空间,但我尽量避免使用全局变量。感谢您的回答,我要么选择我提到的两种方法,要么使用@pkozlowski.opensource 描述的ng-init
    • Thiago 的回答和 AngularJS 处理这种事情恕我直言存在问题。根据@pkozlowski.opensource 的说法,“AngularJS 专注于 Web2.0,即全客户端 Web 应用程序。目前它与服务器端生成内容的配合并不理想。”但是使用 "you.com/#/blog/123" 和 "$route and $html to get the blog content" 属于另一组与 JavaScript 虚拟机和 hashbang 的依赖相关的客户端问题,他们说它破坏了网络 (isolani.co.uk/blog/javascript/BreakingTheWebWithHashBangs)。那该怎么办呢?
    【解决方案3】:

    我相信正确的方法是让服务器使用value provider 呈现脚本,然后将其依赖注入到您的应用程序中。像这样:

    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 ];
        }
    }]);
    

    【讨论】:

    • 将 php 添加到已经很复杂的情况对我来说似乎并不好。
    猜你喜欢
    • 2016-06-12
    • 2014-11-29
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2021-07-05
    • 2020-07-08
    相关资源
    最近更新 更多