missbach/snooper-components

1.5.0 2020-09-03 05:28 UTC

This package is not auto-updated.

Last update: 2024-09-26 01:28:17 UTC


README

设置项目

安装

要通过Composer安装,请将以下行添加到项目根目录中的composer.json文件中:

{
    ...
    require: {
    ...
    "snooper/components": "1.*"
    }
    ...
}

执行Composer

composer update

你应该会看到类似以下内容:

Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
Package operations: 1 install, 0 updates, 0 removals
  - Installing snooper/components (1.0.0): Loading from ...

过程完成后,你就可以开始使用了

Snooper::instance()->....

实现

创建一个提供者

现在你需要实现一个监听器来监听事件。每个提供者可以监听多个事件。让我们开始吧。

<?php
namespace App\Providers;

use Snooper\Components\Provider\Provider;
use Snooper\Components\EventTrigger;
use Snooper\Components\Provider\ProviderCallDefinition;

class TestProvider extends Provider
{
    public function isActive()
    {
        return true;
    }

    public function getEvents()
    {
        return [
            'some.event'=>ProviderCallDefinition::create('someEvent')
        ];
    }

    public function someEvent(EventTrigger $e)
    {
    }
}

好的,那么我们如何让提供者的动作充满活力呢?

<?php
namespace App\Providers;

...
use Snooper\Components\Response\Builder;

class TestProvider extends Provider
{
    ...
    public function someEvent(EventTrigger $e)
    {
        $helloWorld = $e->getParameters()->get('some_variable');
        
        return Builder::createStandardResponse(
            Builder::createDeliver('head'),
            'console.log',
            Builder::createParameter($helloWorld,false)
        );
    }
}

添加到你的引导过程中

Snooper::instance()->getConfig()->setDebugMode(true);

Snooper::instance()->addProvider(new TestProvider());

Snooper::instance()->raiseEvent('some.event',['some_variable'=>'hello world']);

echo Snooper::instance()->outputSection('head');

提示:你可以通过构造函数注入任何你喜欢的服务,因为它们在这个过程中没有被使用。

配置

配置是一个原始的PHP数组

protected $rawParameters = [
        'first_section' => 'head',
        'last_section' => 'footer',
        'sections' => [
            'head','body','footer'
        ],
        'json_response_key' => 'snooper_data',
        'xhr_send_mode'=>self::XHR_SEND_METHOD_BOTH,
        self::DEBUG => [
            'nested_level' => 25,
            'url_param' => 'snooper_debug',
            'session_param' => 'snooper_debug',
            'debug_environments' => [
                'dev'
            ]
        ],
        'log' => [
            'excludeClass' => [
                'Doctrine\ORM\PersistentCollection'
            ]
        ],
        'ignoredRoutes' => [
            '/\/admin$/'
        ]
    ];

Config类知道一个方法"mergeConfig"。你可以随意重写它以满足你的需求。

运行

转到你的页面,刷新它,并打开浏览器中的开发者工具,查看JavaScript控制台。你应该看到类似以下内容

...
hello world
...
------------ SNOOPER EVENTS BEGINS ------------
Event some.event fired.
Object { ..... }
Calls "console.log" with:
hello world
------------- SNOOPER EVENTS ENDS -------------

提示:"SNOOPER 事件开始"和"SNOOPER 事件结束"之间的输出只是调试输出。

恭喜!现在你的第一个事件已从服务器发送到前端进行处理。

什么工作

提供者

在提供者基类中,有几个方法可以使用,你可以重写它们。要自定义HTML或JavaScript标签的输出,请使用getHeadSection,例如,要包含一个外部脚本

<?php
...
class TestProvider extends Provider
{
    ...
    public function getHeadSection()
    {
        return '<script type="text/javascript" async="" src="https://#/analytics.js"></script>';
    }
    ...
}

调用方法的名称取决于你想要使用的部分。模式是"get###Section",例如,对于"footer"使用getFooterSection。

<!DOCTYPE html>
<html>
    <head>
        <?php echo Snooper::instance()->outputSection('head');?>
    </head>
    <body>
        ...
        Content goes here!
        ...
    </body>
</html>

最终结果是

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" async="" src="https://#/analytics.js"></script>
    </head>
    <body>
        ...
        Content goes here!
        ...
    </body>
</html>

提示:输出不依赖于事件,始终打印。但请注意,提供者必须处于活动状态(参见isActive()方法)。

接下来是两个在注册的每个提供者上都会调用的事件,无论触发的事件是否在此提供者中列出或需要,就像输出打印一样。它们被称为"preRaiseEvent"和"postRaiseEvent",方法也接受EventTrigger作为参数。记住跟踪示例,并添加这两个方法

<?php
...
class TestProvider extends Provider
{
    ...
    public function preRaiseEvent(EventTrigger $e)
    {
    }

    public function postRaiseEvent(EventTrigger $e)
    {
    }
    ...
}

好的,让我们看看函数调用的顺序

- Event "some.event" are called.
- Get the first provider.
- Is it Active? (have a look on isActive())
- Yes.
- Call preRaiseEvent.
- Is there a listener for the event "some.event"?
- Yes.
- Ok, call it. (in our case it´s the method someEvent())
- Call postRaiseEvent.
- Is there another provider?
- No. Finish the process.

注意:每个给定EventTrigger对象的方法都可以返回几个东西:无、单个响应或响应数组。响应可以是StandardResponse或InteractionResponse。

可用的设置可以扩展如下

<?php
...
class TestProvider extends Provider
{
    ...
    public function getEvents()
    {
        return [
            'some.event'=>ProviderCallDefinition::create(
                'someEvent',
                ['testkey'=>'testvalue'],
                ProviderCallDefinition::PRIORIZATION_STANDARD
                )
        ];
    }

    public function someEvent(EventTrigger $e, $additional)
    {
        //$addtional => ['testkey'=>'testvalue']
        ...
    }
}

第二个参数可以是任何你想注入方法中的东西。第三个定义了在存在多个监听同一事件的提供者时,每个提供者中调用方法的优先级。

事件触发器

以下是你可以在对象中找到的列表方法

stopPropagation() : cancels any subsequent processing
isPropagationStopped(): checks for cancellation
getParameters() : returns a Bag(Snooper\Components\Utility\Bag), filled with sended parameters
getEventName() : returns the currently raised event (in our case "some.event")
getContext() : returns the context
setContext() : set the context, can be whatever you want

标准响应

构造函数需要精确地传递三个参数。第一个参数是强制的

<php
...
Builder::createStandardResponse(Builder::createDeliver('head'));

这定义了渲染的部分。

<php
Builder::createDeliver('head',Deliver::PRE_SECTION)

可以将输出移至getHeadSection静态方法之前。

提示:请记住,如果跟踪信息在未按此顺序进行的javascript ajax调用之后交付和执行,则它们将按注册的顺序执行。getHeadSection或getBodySection静态方法也将被忽略。

第二个参数也是强制的。它定义了将调用哪个javascript方法。

<php
...
Builder::createStandardResponse(Builder::createDeliver('head'),'console.log');

这将生成以下javascript代码...

console.log();

...日志将如下所示

...

...
------------ SNOOPER EVENTS BEGINS ------------
Event some.event fired.
Object { .... }
Calls console.log without parameters.
------------- SNOOPER EVENTS ENDS -------------

第三个参数定义发送给调用javascript方法的给定信息

<php
...
Builder::createStandardResponse(
    Builder::createDeliver('head'),
    'console.log',
    Builder::createParameter(['test'=>'some information'],false));

在javascript...

console.log({"test":"some information"});

...日志

...
Object { test: "some information" }
...
------------ SNOOPER EVENTS BEGINS ------------
Event some.event fired.
Object { ... }
Calls console.log with:
Object { test: "some information" }
------------- SNOOPER EVENTS ENDS -------------

让我们更仔细地看看 "Builder::createParameter"。第二个参数使得可以在前端执行第二个参数,并使用其结果。看看这个例子

<php
...
Builder::createParameter('{id:document.location.href}', false);

这将导致类似的结果

...
{href:document.location.href}
...
------------ SNOOPER EVENTS BEGINS ------------
Event some.event fired.
Calls console.log with:
{href:document.location.href}
------------- SNOOPER EVENTS ENDS -------------

嗯,好吧,这不是我们想要的。让我们在代码中稍作修改,将 false 改为 true

<php
...
Builder::createParameter('{id:document.location.href}', true);

现在我们再试一次

...
Object { href: "http://?????.de/" }
...
------------ SNOOPER EVENTS BEGINS ------------
Event some.event fired.
...
  Eval executed: {href:document.location.href}
Object { href: "http://?????.de/" }
------------- SNOOPER EVENTS ENDS -------------

是的!这允许对象被添加只有在前端可用的数据。

如果您需要向您的javascript函数发送多个参数,您可以轻松地这样做

<php
...
Builder::createParameter('param1', true, 'param2', true [,....]), 

提示:您必须始终指定参数对。否则,脚本将引发异常。

InteractionResponse

构造函数接收4个参数。示例

<?php
Builder::createInteractionResponse(
    Builder::createInteractionFreeSelector('.test',Interaction::ON_CLICK),
    'console.log',
    Builder::createParameter('hello world'),
    Builder::createInteractionOptionDelay(5000),Builder::createInteractionOptionSendFrontendTarget(SendFrontendTarget::SEND_FE_TARGET_LAST
);

第一个 参数定义了哪个元素应该监听哪种类型的事件

<?php
Builder::createInteractionFreeSelector('.test',Interaction::ON_CLICK); // selector: ".test"

Builder::createInteractionSnooperTarget('test',Interaction::ON_CLICK); // selector: "data-snooper-event='test'"

第二个第三个 参数与在 StandardResponse 中描述的方式完全相同。

最后一个 参数是可以按任意顺序调用的交互选项列表。 "Builder::createInteractionOptionDelay(5000)" 将javascript延迟给定的时间(毫秒)。"Builder::createInteractionOptionSendFrontendTarget(SendFrontendTarget::SEND_FE_TARGET_LAST)" 将发送的源元素添加到javascript方法中。

VariableSet

构造函数接收3个参数。示例

<?php
Builder::createVariableSet(
    Builder::createDeliver('head'),
    'test',
    Builder::createParameter('hello world')    
);

在这个例子中,window作用域中的变量 "test" 将被设置为 "hello world" 的值。

Raw

构造函数接收2个参数。示例

<?php
Builder::createRaw(
    Builder::createDeliver('head'),
    'alert("test")'    
);