如何在 AngularJS 的索引页面上使用来自 Node.js 的信息

Posted

技术标签:

【中文标题】如何在 AngularJS 的索引页面上使用来自 Node.js 的信息【英文标题】:How do I use information from Node.js on an index page in AngularJS 【发布时间】:2017-05-21 15:45:44 【问题描述】:

我目前是 MEAN 堆栈的新手,基本上我有一个基本的应用程序。

我在 localhost 上运行节点服务器,因此 Node.js 服务于索引页面

var index = require('./routes/index');
app.use('/', index);

路由器看起来像这样:

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) 

);

module.exports = router;

所以没什么特别的,它是一个空路由器。首先,我想了解这个路由器是如何为那个 html 页面提供服务的?我不应该做一个 render() 什么的吗?

我的下一个问题是,如何从 Node.js 获取数据并将其提供给初始 GET 请求并在 Angular 端使用该数据?

我知道另一种方法是发送另一个 GET 请求并使用响应数据并将其绑定到范围变量。我的意思是:

var app = angular.module('myApp');

app.controller('myController', function($scope, $http)

    $scope.data = [''];

    getData(); //Call getData to go to server and retrieve the data I want

    function getData() 
        $http
            .get('/')
            .success(function(data)
                $scope.data = data;
            );
        );
    

);

在我看来,基本上,有 2 个 GET 请求正在发出。当我转到 localhost:3000/ 并加载我的 HTML 页面时,然后在 HTML 页面中加载控制器时(通过 getData 完成)。有没有办法将其减少为一个 GET 请求(最好在初始请求中)?

【问题讨论】:

“首先我想了解这个路由器是如何为那个 HTML 页面提供服务的?”——我完全不明白它是如何做任何事情的。当我运行代码时,它显示:ReferenceError: app is not defined。您的minimal reproducible example 中是否缺少某些内容? 为什么要减少到一个请求?将静态 html 的服务与应用程序数据的提供分开是一种更具可扩展性的模式。 @Quentin 这不是最小的、完整的、可验证的,因为我删除了一些代码以使其更易于阅读。如果 ReferenceError 来自服务器端,您可能需要添加使用 express 框架的var app = express() @Sahil — 您应该提供minimal reproducible example。据推测,它设法呈现页面的原因是因为您没有包含代码。 @Belfordz 我可以毫无困难地提出两个请求,尤其是因为这个应用程序很小,但我认为最好只有一个。 【参考方案1】:

看看this express docs page about templating engines

您要做的是为您的索引文件提供一个模板而不是 html。首先我们需要告诉我们的 express 应用我们想要什么渲染引擎

app.set('view engine', 'ejs');

现在我们要定义我们的索引路由,其中​​索引路由返回我们以特定方式插入的 html + 数据。

app.get('/', function (req, res) 
  res.render('index',  allThemDatas:  username: 'pleb', password: 'password'  )
)

您可以重写索引文件以使用特定的模板语法。 ejs 是一种可以使这样做变得非常容易的方法,因此我们将使用它。我们只想获取原始 index.html 文件并将以下内容添加到头部或任何地方:

...
<head>
  <script>
    var userdata = <%= allThemDatas %>;
  </script>
</head>
...

从这里,您可以只使用window.userdata,或者更可测试的角度方法是使用角度常数。

angular
.module('userdata', [])
.constant("data", <%= allThemDatas %>)

作为完全另一种选择,通过使用 angular ui-router 和 resolve's,您可以使用 $http 从服务器获取数据,并且解析会将 $http 请求的结果注入到您的视图中控制器为您服务。

【讨论】:

假设我有 allThemDatas 需要绑定到需要在该 HTML 页面上显示的 $scope.data 变量? ejs 模板userdata$scope.data 不会冲突吗?还是默认情况下我可以在 ejs 文件中执行类似$scope.data = userdata 的操作?我开始认为,这只会使事情复杂化,最好对静态页面发出第一个 GET 请求,对数据发出第二个 GET 请求。 从您的 cmets 看来,您需要一种 简单 的方式来获取来自 GET 请求的响应到您的视图中。 view -> controller -> service -> route 模式是可扩展的,这意味着它分离了关注点,这就是你想要的代码。从长远来看,这种模式更容易测试,更容易维护。 我想我现在更明白了。我认为正在发生的事情是 service -> route -> view 当你最初输入你的 URL 时......我试图把 controller 放在 view 之前,这是行不通的。跨度> @ilovecoding 已更新,希望在这里提供更清晰的信息。【参考方案2】:

您的节点路由器设置了一个路由,您的 Angular 服务方法可以向该路由发出 GET 请求。

所以,为了说明:

router.get('/', function(req, res, next) 
  res.send("something");
);

如果您选择这样做,这实际上会发出GET 请求并收集响应。如上图所示,您可以发送任何您想要的响应——在本例中,是字符串“something”。将其视为一个端点。

在您的角度服务(我认为不是控制器)中,您可以发出GET 请求:

app.service('DataService', function(DataService)
    function getData() 
        $http
            .get('/')
            .success(function(data)
                $scope.data = data; // data will be "something"
            );
        );
    
);

这实际上是向该端点发出请求并为您的控制器提供响应。您可能希望在视图中使用此响应或对其执行某些操作。

然后,像这样在你的控制器中注入这个服务:

app.controller('MyController', ['DataService', function(DataService)
    //...
     DataService.getData().then(function(data)
        // do something with data
     );

【讨论】:

我了解如果我想发出 GET 请求,该路由将为该请求提供响应,我可以在服务或工厂中使用该响应。我感到困惑的是,当您在浏览器中键入“localhost:3000”时,浏览器会发送一个 GET 请求,但我如何访问该初始请求?有没有办法从客户端发出的第一个 GET 请求中获得响应?你总是必须做第二个吗? 您也可以完全控制它!当您第一次启动服务器时,您可以告诉它根路径将是什么。 /localhost:3000 映射到的根路径。如果需要,您可以将 localhost 映射到 /whatever

以上是关于如何在 AngularJS 的索引页面上使用来自 Node.js 的信息的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 自动完成 + AngularJS 的问题

Rails - 在项目模型的索引页面上显示来自客户端模型的数据

如何在 AngularJS 中使用 $http.get 从 jsp 页面获取响应?

AngularJS - 如何验证 URL 动态参数

如何在 Jekyll 中使用 markdownify 在索引中显示摘录

来自url的Angularjs json不起作用,但在本地工作