jqh 5 年之前
父節點
當前提交
3084212c08
共有 5 個文件被更改,包括 140 次插入4 次删除
  1. 1 0
      src/Admin.php
  2. 37 0
      src/Controllers/RenderableController.php
  3. 1 1
      src/Grid/Column.php
  4. 48 3
      src/Grid/Displayers/Modal.php
  5. 53 0
      src/Support/RemoteRenderable.php

+ 1 - 0
src/Admin.php

@@ -250,6 +250,7 @@ class Admin
                 $router->post('action', 'HandleActionController@handle')->name('action');
                 $router->post('form', 'HandleFormController@handle')->name('form');
                 $router->post('value', 'ValueController@handle')->name('value');
+                $router->get('render', 'RenderableController@handle')->name('render');
                 $router->post('tinymce/upload', 'TinymceController@upload')->name('tinymce.upload');
                 $router->post('editor-md/upload', 'EditorMDController@upload')->name('editor-md.upload');
             });

+ 37 - 0
src/Controllers/RenderableController.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Dcat\Admin\Controllers;
+
+use Dcat\Admin\Admin;
+use Dcat\Admin\Support\Helper;
+use Dcat\Admin\Support\RemoteRenderable;
+use Illuminate\Http\Request;
+
+class RenderableController
+{
+    /**
+     * @param Request $request
+     *
+     * @return mixed|string
+     */
+    public function handle(Request $request)
+    {
+        $class = $request->get('renderable');
+        $key = $request->get('key');
+
+        $class = str_replace('_', '\\', $class);
+
+        if (class_exists($class)) {
+            return $this->render(new $class($key));
+        }
+
+        return $class;
+    }
+
+    protected function render($renderable)
+    {
+        return Helper::render($renderable->render())
+            .Admin::asset()->scriptToHtml()
+            .Admin::asset()->styleToHtml();
+    }
+}

+ 1 - 1
src/Grid/Column.php

@@ -30,7 +30,7 @@ use Illuminate\Support\Traits\Macroable;
  * @method $this expand($callbackOrButton = null)
  * @method $this table($titles = [])
  * @method $this select($options = [])
- * @method $this modal($title = '', \Closure $callback = null)
+ * @method $this modal($title = '', $callback = null)
  * @method $this showTreeInDialog($callbackOrNodes = null)
  * @method $this qrcode($formatter = null, $width = 150, $height = 150)
  * @method $this downloadable($server = '', $disk = null)

+ 48 - 3
src/Grid/Displayers/Modal.php

@@ -2,13 +2,17 @@
 
 namespace Dcat\Admin\Grid\Displayers;
 
+use Dcat\Admin\Admin;
 use Dcat\Admin\Support\Helper;
+use Dcat\Admin\Support\RemoteRenderable;
 use Illuminate\Support\Str;
 
 class Modal extends AbstractDisplayer
 {
     protected $title;
 
+    protected $renderable;
+
     public function title(string $title)
     {
         $this->title = $title;
@@ -21,6 +25,39 @@ class Modal extends AbstractDisplayer
         return 'grid-modal-'.$this->grid->getName().$key;
     }
 
+    protected function addRenderableModalScript(string $modalId, string $url)
+    {
+        $script = <<<JS
+(function () {
+    var modal = $('#{$modalId}');
+    
+    modal.on('show.bs.modal', function (e) {
+        modal.find('.modal-body').html('<div style="min-height:150px"></div>');
+    
+        modal.find('.modal-body').loading();
+        
+        $.ajax('{$url}').then(function (data) {
+            modal.find('.modal-body').html(data);
+        });
+    })
+})();
+JS;
+
+        Admin::script($script);
+    }
+
+    protected function setUpRemoteRenderable(string $modalId, $renderable)
+    {
+        /* @var RemoteRenderable $renderable */
+        if (is_string($renderable)) {
+            $renderable = $renderable::make($this->getKey());
+        }
+
+        $this->addRenderableModalScript($modalId, $renderable->getUrl());
+
+        $renderable::collectAssets();
+    }
+
     public function display($callback = null)
     {
         $title = $this->trans('title');
@@ -28,15 +65,23 @@ class Modal extends AbstractDisplayer
             [$title, $callback] = func_get_args();
         }
 
+        $title = $this->title ?: $title;
         $html = $this->value;
+        $id = $this->generateElementId();
+
         if ($callback instanceof \Closure) {
             $html = Helper::render(
                 $callback->call($this->row, $this)
             );
-        }
+        } elseif (is_string($callback) && is_subclass_of($callback, RemoteRenderable::class)) {
+            $html = '';
 
-        $title = $this->title ?: $title;
-        $id = $this->generateElementId();
+            $this->setUpRemoteRenderable($id, $callback);
+        } elseif ($callback instanceof RemoteRenderable) {
+            $html = '';
+
+            $this->setUpRemoteRenderable($id, $callback->setKey($this->getKey()));
+        }
 
         return <<<EOT
 <span class="grid-expand" data-toggle="modal" data-target="#{$id}">

+ 53 - 0
src/Support/RemoteRenderable.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace Dcat\Admin\Support;
+
+use Dcat\Admin\Admin;
+use Illuminate\Contracts\Support\Renderable;
+
+abstract class RemoteRenderable implements Renderable
+{
+    protected static $js = [];
+
+    protected static $css = [];
+
+    protected $key;
+
+    public function __construct($key = null)
+    {
+        $this->setKey($key);
+    }
+
+    public function setKey($key)
+    {
+        $this->key = $key;
+
+        return $this;
+    }
+
+    public function getKey()
+    {
+        return $this->key;
+    }
+
+    public function getUrl()
+    {
+        $data = [
+            'key'        => $this->key,
+            'renderable' => str_replace('\\', '_', static::class),
+        ];
+
+        return route(admin_api_route('render'), $data);
+    }
+
+    public static function collectAssets()
+    {
+        Admin::js(static::$js);
+        Admin::css(static::$css);
+    }
+
+    public static function make(...$params)
+    {
+        return new static(...$params);
+    }
+}