【问题标题】:How to build an AngularJS app with Yesod如何使用 Yesod 构建 AngularJS 应用程序
【发布时间】:2015-01-14 05:51:12
【问题描述】:

我成功地使用 Yesod 编写了一个小应用程序。现在我正处于想要为其添加更好交互的阶段,我想使用 AngularJS 来做到这一点。

据我所知,Yesod 对 AngularJS 的支持仍处于试验阶段。此外,到目前为止,我发现的文档对我来说是完全无法访问的。我没有掌握所有 Yesod 概念。

所以我想知道,集成 AngularJS 和 Yesod 框架的可能方法是什么。我正在考虑做的是:

  1. 用 AngularJS 编写前端。
  2. 使用 Yesod 开发 Web 服务。
  3. 通过 GET 和 POST http 请求连接前端和 Web 服务。信息可以通过输入表单发送到服务器(通过这种方式利用Yesod的一些能力),信息可以通过JSON对象发送到前端。

理想情况下,我想用 Haskell 编写所有内容,但在目前的情况下,这可能是不可能的。因此,我想问一下我想到的替代方案是否不错,以及是否有改进的方法。

谢谢。

【问题讨论】:

标签: javascript json angularjs haskell yesod


【解决方案1】:

所以我对 haskell 或 yesod 一无所知,但将 Angular 与 Yesod 集成起来并不难。 请按照这些步骤操作,以最终获得一个正常工作的应用程序!

这是我设置的步骤

  • 按照 Yesod 快速入门设置 Yesod 应用

    brew install haskell-stack

    stack new my-project yesod-sqlite && cd my-project

    stack install yesod-bin cabal-install --install-ghc

    堆栈构建

    stack exec -- yesod 开发

现在您可以访问一个简单的 OTB 网络应用程序here。生成的应用具有以下结构:

  • 我使用 bower 来设置 pull in angular、jQuery 和 bootstrap
  • 我使用了一个自定义的 .bowerrc 文件来拉取静态文件夹中的包

.bowerrc

{
    "directory": "static/bower_modules"
}

bower.json

{
  "name": "my-project",
  "version": "0.0.0",
  "authors": [
      "Atef Haque <atefth@gmail.com>"
  ],
  "description": "Haskell with Angular",
  "keywords": [
      "haskell",
      "angular"
  ],
  "license": "MIT",
  "ignore": [
      "**/.*",
      "node_modules",
      "bower_components",
      "static/bower_modules",
      "test",
      "tests"
  ],
  "dependencies": {
      "angular": "~1.5.3",
      "angular-route": "~1.5.3",
      "bootstrap": "~3.3.6"
  }
}

运行 bower install 会在 static/bower_packages 目录中安装包

  • 现在我分别在 static/scripts 和 static/templates 目录中添加了我的脚本和模板

app.js

var app = angular.module('app', ['ngRoute']);

app.run(['$rootScope', function ($rootScope) {
    $rootScope.title = 'home';
}]);

app.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
    .when('/', {
        templateUrl : 'static/templates/layout.html',
        controller  : 'HomeCtrl'
    });
}])

app.controller('HomeCtrl', ['$scope', 'Comment', function ($scope, Comment) {
    $scope.comments = [];
    $scope.post = function () {
        Comment
        .post($scope.message)
        .success(function (data) {
            $scope.comments.push(data);
        })
        .error(function (error) {
            console.log(error);
        });
    };
}])

app.service('Comment', ['$http', function ($http) {
    this.post = function (comment) {
        return $http
        .post('http://localhost:3000/comments', {message: comment})
    }
}])

layout.html

<div class="jumbotron">
    <div class="container">
        <div class="page-header" align="center">
          <h1>Haskell <small>+</small> Angular</h1>
        </div>
        <div class="well well-lg">
            <div class="row">
                <div class="col-lg-12">
                <form role="form" ng-submit="post()">
                        <legend>Post a comment</legend>
                        <div class="form-group">
                            <label for="">Message</label>
                            <input type="text" class="form-control" placeholder="Message" ng-model="message">
                        </div>
                        <button type="submit" class="btn btn-primary">Comment</button>
                    </form>
                </div>
            </div>
            <hr style="border: 2px solid steelblue">
            <div class="row">
                <div class="col-lg-6" ng-repeat="comment in comments">
                    <div class="panel panel-info">
                        <div class="panel-heading">
                            <h3 class="panel-title">Comment #{{ comment.id }}</h3>
                        </div>
                        <div class="panel-body">
                            {{ comment.message }}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

至此,我们都在前端进行了设置。现在我必须将后端配置为只提供一个 index.html ,其中 angular 可以接管!

  • 我编辑了 templates/default-layout-wrapper.hamlet 并删除了大部分默认内容

default-layout-wrapper.hamlet head

<!doctype html>
<html lang="en" ng-app="app">
  <head>
    <meta charset="UTF-8">

    <title>{{ title }}
    <meta name="description" content="">
    <meta name="author" content="">

    <meta name="viewport" content="width=device-width,initial-scale=1">

    <style link="rel" src="static/bower_modules/bootstrap/dist/css/bootstrap.min.css">

    ^{pageHead pc}

default-layout-wrapper.hamlet 正文

<body>
    <div class="container" ng-controller="HomeCtrl">
      <div ng-view>
    <script type="text/javascript" src="static/bower_modules/jquery/dist/jquery.min.js">
    <script type="text/javascript" src="static/bower_modules/bootstrap/dist/js/bootstrap.min.js">
    <script type="text/javascript" src="static/bower_modules/angular/angular.js">
    <script type="text/javascript" src="static/bower_modules/angular-route/angular-route.min.js">
    <script type="text/javascript" src="static/scripts/app.js">

不幸的是 Stackoverflow 可能不允许 hamlet code sn-ps 所以我不得不将它分开

现在,当您使用 here 时,您将拥有一个带有由 yesod 后端驱动的 Angular 前端的 Web 应用程序。


看似魔法的事物

  1. 在没有任何后端代码的情况下发布 cmets 是否有效?不,它来自 OTB :)

希望我能比他们更清楚地思考!

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-02-18
  • 2016-02-21
  • 1970-01-01
  • 2017-04-14
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 2012-12-09
相关资源
最近更新 更多