codekanzlei/cake-frontend-bridge

前端桥接 CakePHP 3

安装次数: 49,974

依赖关系: 7

建议者: 0

安全性: 0

星标: 6

关注者: 4

分支: 4

开放问题: 7

语言:JavaScript

类型:cakephp-plugin


README

CakePHP 3 Notifications Plugin License

一个允许创建用于控制器操作的JavaScript控制器的CakePHP 3插件。也可以通过shell进行代码生成。

依赖项

安装

1. 在 composer.json 中要求插件

"require": {
	"codekanzlei/cake-frontend-bridge": "dev-master",
}

2. 使用composer包含插件

在您的项目文件夹中打开终端并运行

$ composer update

3. 在 config/bootstrap.php 中加载插件

Plugin::load('FrontendBridge', ['bootstrap' => true, 'routes' => true, 'autoload' => true]);

4. 创建额外的文件

创建以下文件,并使用提供的代码进行设置。

  • app_controller.js

    路径:/webroot/js/app/

    模板代码

     Frontend.AppController = Frontend.Controller.extend({
         baseComponents: [],
         _initialize: function() {
             this.startup();
         }
     });
    

5. 配置 AppController.php

在您的 src/Controller/AppController.php 中插入以下代码以设置前端桥接插件。

特质

use \FrontendBridge\Lib\FrontendBridgeTrait;

$helpers

'FrontendBridge' => ['className' => 'FrontendBridge.FrontendBridge'],

$components

'FrontendBridge.FrontendBridge',

6. 加载脚本

在您的 <head> 部分添加以下代码以加载所有所需的.js控制器

<?php if(isset($this->FrontendBridge)) {
	$this->FrontendBridge->init($frontendData);
	echo $this->FrontendBridge->run();
} ?>

在开发中,将 $this->FrontendBridge->addAllControllers(); 添加到if块中,以加载所有.js控制器而无需异常

7. 添加主内容类

在您的 Layout\default.ctp 中添加以下行。在div中应该是您的内。

<div <?= $this->FrontendBridge->getControllerAttributes(['some', 'optional', 'css', 'classes']) ?>>
    ...
    <?= $this->fetch('content') ?>
    ...
</div>

如果您使用其他布局文件,也请添加此代码。

烘焙JS控制器

您可以使用bake shell为您的控制器操作烘焙JS控制器。只需传递控制器名称和驼峰式的操作名称即可。

bin/cake bake js_controller Posts addPost

此命令将创建JavaScript控制器文件,并在必要时创建其目录结构。

您还可以使用--plugin选项将JS控制器烘焙到插件中。

代码示例

使用以下示例代码片段以更好地理解前端桥接插件及其有用的功能。请注意,您可能需要包含其他插件来实现这些功能。

1.) 在js控制器中访问视图变量

使用以下基本设置,通过前端桥接将数据从后端传递到前端。

  • YourController.php (CakeController)

     action() {
     	$this->FrontendBridge->setJson(
     		'varName',
     		'this is sample text');
     }
    
  • action.ctp (Cake 视图文件)

     display content of json var
     <span class="findMe"></span>
    
  • action_controller.js (前端桥接JS-控制器)

     startup: function() {
     	var varName = this.getVar('varName');
     	$('findMe').text(varName);
     }
    

请务必注意命名约定,特别是关于action_controller.js的。根据上面所示的示例,其确切路径应为/webroot/js/app/controllers/your/action_controller.js

您已通过变量varName从控制器传递到前端的变量现在应该在视图中渲染。

2.) 使用模态对话框编辑表单

此示例使用以下其他插件

使用以下基本设置,使用模态视图元素作为编辑表单,并通过前端桥接将更改请求数据传递到后端。为此示例,我们将使用基本的Users-模型以及一个模态表单元素,嵌入到用于编辑和保存用户实体的一些属性的正常视图页面中。

  • UsersController.php (CakeController)

     public function editModal ($id = null) {
     	$user = $this->Users->get($id);
     	if ($this->request->is(['patch', 'post', 'put'])) {
     		$user = $this->Users->patchEntity($user, $this->request->data);
     		if ($this->Users->save($user)) {
     			// prevent redirecting or reloading of the current page
     		    $this->FrontendBridge->setJson('success', true);
     		}
     	}
     	$this->set(compact('user'));
     }
    
  • view.ctp (常规Cake视图文件;在它前面是edit_modal.ctp)

     // CkTools button
     <?=$this->CkTools->button('edit_label', [
     	'controller' => 'Users',
     	'action' => 'editModal',
     	$user->id
     	],
     	// block interaction with the view file 'behind' the modal element
     	['additionalClasses' => 'modal-form']
     )?>
    
  • edit_modal.ctp (视图文件,将作为模态表单的内容)

     <div class="modal-content">
     	<div class="modal-header">
     		<button type="button" class="close" data-dismiss="modal">&times;</button>
     	</div>
     	<div class="modal-body">
     		<?= $this->Form->create($user, [
                 'class' => 'dialog-ajax-form dialog-ajax-form-close-on-success',
                 'novalidate',
             ]);?>
     	        <fieldset>
     	            <?= $this->Form->input('name'); ?>
     	            // [further input fields]
     	        </fieldset>
    
     	        <div class="modal-footer">
     	        	// FormEnd (save) button generated using CkTools
     	            <?= $this->CkTools->formButtons(['cancelButton' => false]); ?>
     	        </div>
             <?= $this->Form->end(); ?>
     	</div>
     </div>
    
  • edit_modal_controller.js (前端桥接JS-控制器)

     startup: function() {
     	//  add an EventListener to element with class 'modal-form'
     	this.$('.modal-form').on('click', function(e) {
     		// callback function when Listener is triggered
             e.preventDefault();
             App.Main.Dialog.loadDialog($(e.currentTarget).attr('href'), {
                 modalTitle: 'Modal title',
                 preventHistory: false
             });
         });
     }
    

3.) 生成自定义AJAX请求

使用以下设置来生成自定义的AJAX请求。使用FrontendBridge的'request'动作,我们将从后端传递JSON数据到前端。

  • YourController.php (CakeController)

     public function getJsonData()
     {
         $code = ApiReturnCode::SUCCESS;
         return $this->Api->response($code, [
             'foo' => 'bar',
             'more' => 'json-data'
         ]); // JSON data which will be logged in your browser console
     }
    
  • index.ctp(Cake视图文件)

     <a class="ajax-json-demo">Get JSON data</a>
    
  • index_controller.js(FrontendBridge JS-控制器)

     App.Controllers.YourIndexController = Frontend.AppController.extend({
     	startup: function() {
     		this.$('.ajax-json-demo').click(function() {
                 var url = {
                     controller: 'Your',
                     action: 'getJsonData'
                 };
                 // if postData is null, a GET request will be made
                 var postData = null;
                 App.Main.request(url, postData, function (response) {
                     alert('Response Code ' + response.code + ' - see console for details');
                     console.log(response.data);
                 });
             }.bind(this));
     	}
     });
    

4.) 使用AJAX动态加载内容

使用以下设置通过AJAX进行自定义HTML请求。使用FrontendBridge的loadJsonActionrequest,我们将实现一个非常基本的实时搜索。

此示例假定您的数据库中有一个名为Users的表,其中有一个名为username的字段。

  • SearchController.php(Cake控制器)

     public function index() {
     	// renders index.ctp
     }
    
     public function search() {
         $users = null;
         if ($this->request->is(['patch', 'post', 'put']) && !empty($this->request->data['search'])) {
         	// search UsersTable for entities that contain
         	// request->data['search'] in field 'username'
             $users = TableRegistry::get('Users')->find()
                 ->where(['username LIKE' => '%' . $this->request->data['search'] . '%'])
                 ->all();
         }
         $this->set(compact('users'));
     }
    
  • index.ctp(Cake视图文件)

     <!-- input field -->
     <div class="input-group">
     	<input type="text" class="form-control" id="search">
     </div>
     <br />
     <!-- search results (search.ctp) will be rendered here -->
     <div class="results"></div>
    
  • search.ctp(Cake视图文件)

     <?php if(!empty($users)) : ?>
     	<?php foreach($users as $user) : ?>
     		<?= h($user->username) ?><br />
     	<?php endforeach; ?>
     <?php else : ?>
     	no results to display
     <?php endif; ?>
    
  • index_controller.js(FrontendBridge JS-控制器)

     App.Controllers.SearchIndexController = Frontend.AppController.extend({
         startup: function() {
         	// set KeyUp-EventListener to field with id 'search' in index.ctp
             this.$('#search').keyup(this._search.bind(this));
         },
    
         // called at eatch keyup-event in 'search'
         _search: function() {
             var $renderTarget = this.$('.results');
             var url = {
                 controller: 'Search',
                 action: 'search'
             }
    
             // create a custom AJAX request with the user input included in the post-data
             App.Main.loadJsonAction(url, {
                 data: {
                     search: this.$('#search').val()
                 },
                 target: $renderTarget, // render the HTML into this selector
             });
         }
     });
    

功能概述

  • loadJsonAction

    允许根据用户交互动态地在视图中加载内容。使用request

  • request

    允许生成自定义AJAX请求。也支持FormData(除IE <= 9外)作为请求数据。