sokil / frontend-bundle

此软件包已被弃用且不再维护。没有建议的替代包。

前端组件,用于快速启动前端应用程序

0.12.7 2017-03-12 13:31 UTC

This package is auto-updated.

Last update: 2021-12-09 18:23:08 UTC


README

基于 Backbone、Marionette 和 Twitter Bootstrap 的单页面应用程序

Total Downloads Build Status

安装

添加 composer 依赖项

composer require sokil/frontend-bundle

将捆绑包添加到 AppKernel

<?php

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new Sokil\FrontendBundle\FrontendBundle(),
        );
    }
}

构建资源

bower install
npm install
grunt

捆绑包使用 assetic,因此您需要在 assetic 配置中注册它

assetic:
    bundles:
        - FrontendBundle

您可以使用 DeployBundle 来处理静态资源的部署过程。

控制器

单页面应用程序

我们可以配置一个预定义的控制器,负责渲染单页面应用程序,并将其作为服务

acme.spa.controller:
  class: Sokil\FrontendBundle\Controller\IndexController
  arguments:
    - 'AcmeBundle:Spa:index.html.twig'
  calls:
    - [setContainer, ["@service_container"]]

或使用您自己的控制器

<?php

namespace Acme\SiteBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class SpaController extends Controller
{
    public function indexAction(Request $request)
    {
        if (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
            throw $this->createAccessDeniedException();
        }

        // render response
        return $this->render('SiteBundle:Spa:index.html.twig', [
            'applicationData' => $this->get('acme.spa.app_data')->getData(), // optional appdata
        ]);
    }
}

在下面的 视图部分 中查看如何配置 spa 的示例 SiteBundle:Spa:index.html.twig

如果需要将一些额外的数据从后端传递到前端,这可以通过 应用数据 完成。

应用数据

应用数据可以用来从后端传递一些数据到前端。创建一个服务,负责从不同来源获取应用数据

acme.spa.app_data:
    class: Sokil\FrontendBundle\Spa\ApplicationData

现在将此服务的名称传递给您的 spa 动作的定义

acme.spa.controller:
  class: Sokil\FrontendBundle\Controller\IndexController
  arguments:
    - 'AcmeBundle:Spa:index.html.twig'
    - '@acme.spa.app_data'
  calls:
    - [setContainer, ["@service_container"]]

应用数据来自多个提供者。提供者是一个服务,由标签 frontend.spa.app_data_provider 标识。此外,app 数据服务必须通过键 app_data 定义,指向应用数据服务的实例。

acme.spa.some_app_data_provider;
    class: Acme\Spa\SomeApplicationDataprovider
    tags:
        - {name: frontend.spa.app_data_provider, app_data: acme.spa.app_data}
    

提供者类必须实现 Sokil\FrontendBundle\Spa\ApplicationDataProviderInterface。它必须实现一个方法 getData(),该方法返回应用参数的映射。

模型

处理 JSON 请求

Backbone 模型发送 JSON 请求。

要启用支持,您可以添加 FOSRestBundle 并配置序列化器。 app/AppKernel.php

new FOS\RestBundle\FOSRestBundle(),

app/config/config.yml:

framework:
    serializer:
        enabled: true
        enable_annotations: true

如果您不需要整个捆绑包,只需注册一个监听器,它将 JSON 请求转换为数组

services:
    json_request_listener:
        class: Sokil\FrontendBundle\EventListener\JsonRequestListener
        tags:
            - {name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: -255 }

视图

模板

视图渲染 Marionette 2 应用程序并启动它。使用 Bootstrap 3 作为 UI 框架。要在页面上添加一些 CSS 和 JS 资源,请使用来自 src/Resources/views/macro.html.twig 的宏。

{% import "@FrontendBundle/Resources/views/macro.html.twig" as frontend %}
<!DOCTYPE html>
<html>
    <head>
        {{ frontend.commonCssResources() }}
    </head>
    <body>
        <div id="content"></div>
        <div id="popup"></div>
    </body>
    {{ frontend.commonJsResources() }}
    <script type="text/javascript">
        (function() {
            // app options may be accessed through applicationData variable
            var options = {{ applicationData|json_encode|raw }};
            // router may be passed as option
            options.router = [
                AcmeRouter
            ];
            // container with fromtend services may be passed as option
            options.serviceDefinition = [
                AcmeServiceDefinition
            ];
            // root element of SPA app
            // optional, `body` used by default
            options.root = 'body';
            // requirejs
            options.requirejs = [
                AcmeRequireJsConfig
            ]
            // regions of root app, optional
            options.regions = {
                content: '#content', // region for content of app
                popup: '#popup'      // region for popup rendering
            }
            // start app
            window.app = new Application(options);
            window.app.start();
        })();
    </script>
</html>

区域

应用程序指的是根视图 app.rootView,该视图处理单页应用(SPA)的根元素。根元素可以在应用程序选项中配置,或者使用默认值 body。根元素包含一些区域,其中渲染不同的功能。主要内容渲染到 app.rootView.content 区域,弹出窗口渲染到 app.rootView.popup 区域。您可以传递自己的区域,并通过 app.rootView 来引用它们。

路由器

路由器是 Backbone.Router 的实例。您还可以使用 Marionette.AppRouter

如果您有少量路由,您可以将它们全部传递到 routers 选项中。

window.app = new Application({
    routers: [
        Bundle1Router,
        Bundle2Router
    ]
});

要设置默认路由,请使用 defaultRoute 选项。

var Bundle1Router = new Backbone.Router({
    routes: {
        '/some/route': 'someRoute'
    },

    someRoute: function() {
        // ...
    }
});

window.app = new Application({
    routers: [
        Bundle1Router,
        Bundle2Router
    ],
    defaultRoute: [Bundle1Router, 'someRoute'];
});

服务容器

容器是一个注册表,用于构建和获取已构建的服务。服务定义只是一个具有构建服务实例的方法的对象,其中 this 指向 Container 实例。

AcmeServiceDefinition = {
    someService: function() {
        return new SomeService(this.get('otherService'));
    },
    otherService: function() {
        return new OtherService();
    }
}

通过 serviceDefinitions 配置参数传递给容器的定义。

options.serviceDefinitions = [
    Bundle1ServiceDefinition,
    Bundle2ServiceDefinition
];

然后可以从容器中获取服务。

var someService = app.container.get('someService');

RequireJs

依赖项可以合并并传递到容器中。

options.requireJs = [
    Bundle1RequireJsConfig,
    Bundle2RequireJsConfig
];

每个配置可能匹配一个或两个 pathshim 参数。

var Bundle1RequireJsConfig = {
    paths: {
        'bundle1_tinymce': 'staticpage/js/tinymce/tinymce.min'
    },
    shim: {
        'bundle1_tinymce': {
            exports: 'tinymce'
        }
    }
};

默认情况下,应用程序已经预先配置了 FrontendRequireJsConfig。它有一些依赖项,例如 Twitter Typeahead。

前端组件

弹出窗口

弹出窗口必须扩展 PopupView

var MyPopupView = PopupView.extend({
    
    events: {
        'click .save': 'saveButtonClickListener'
    },

    title: 'My Popup',
    
    buttons: [
        {class: 'btn-primary save', title: 'Save'}
    ]
}

列表

此组件允许生成模型的集合。

var SomeListView = ListView.extend({
    showColumnHeader: true, // show table header
    
    /**
     * Defines list of columns
     * Array, or function that return array
     * @return {array}
     */
    columns: function() {
        return [
            {
                caption: app.t('SomeListView.some_column_name'), // column caption
                name: 'some_column_name' // column name
            },
        ];
    },

   /**
    * Defines list of buttons, rendered in all rows
    * Array, or function that return array
    * @return {array} 
    */
    buttons: function() {
        return [
            {
                name: 'edit', // button name
                class: 'btn btn-default btn-xs', // button class
                icon: 'glyphicon glyphicon-pencil', // button icon
                caption: app.t('SomeListView.edit'), // button cation
                click: function(e, itemId, view) { // click handler
                     alert('edit');
                }
            }
        ];
    }
});

多类型预测

包装 ListView,并为列表添加添加新元素的类型预测功能。