src/AbstractView.php
<?php
declare(strict_types=1);
namespace Atk4\Ui;
use Atk4\Core\AppScopeTrait;
use Atk4\Core\ContainerTrait;
use Atk4\Core\InitializerTrait;
use Atk4\Core\NameTrait;
use Atk4\Core\StaticAddToTrait;
use Atk4\Core\TrackableTrait;
/**
* Abstract view tree item (used only for View and Callback, you want probably to extend one of these).
*
* @property array<string, AbstractView> $elements
*
* @method View getOwner()
*/
abstract class AbstractView
{
use AppScopeTrait;
use ContainerTrait {
add as private _add;
}
use InitializerTrait {
init as private _init;
}
use NameTrait;
use StaticAddToTrait;
use TrackableTrait;
/**
* If add() method is called, but current view is not part of render tree yet,
* then arguments to add() are simply stored in this array. When the view is
* initialized by calling init() or adding into App or another initialized View,
* then add() will be re-invoked with the contents of this array.
*
* @var list<array{self, array<mixed>}>|null
*/
protected ?array $_addLater = [];
/** Will be set to true after rendered. This is so that we don't render view twice. */
protected bool $_rendered = false;
/**
* Called when view becomes part of render tree. You can override it but avoid
* placing any "heavy processing" here.
*/
protected function init(): void
{
if (($this->name ?? null) === null) {
$this->name = 'atk';
}
$this->_init();
if ($this->_addLater !== null) {
foreach ($this->_addLater as [$object, $args]) {
$this->add($object, $args);
}
$this->_addLater = null;
}
}
/**
* @param array<mixed> $args
*
* @return ($object is View ? View : self)
*/
public function add(self $object, array $args = []): self
{
if ($this->_rendered) {
throw new Exception('You cannot add anything into the view after it was rendered');
}
if (!$this->issetApp()) {
$this->_addLater[] = [$object, $args];
return $object;
}
// will call init() of the object
$this->_add($object, $args);
return $object;
}
}