Cành không cho phép thực hiện việc này trực tiếp. Bạn có thể thêm chức năng đơn giản vào Twig để xử lý việc đóng cửa hoặc đóng bao đóng trong lớp để có thể sử dụng chức năng thuộc tính của Twig (vì gọi trực tiếp attribute(_context, 'myclosure', args)
sẽ kích hoạt Lỗi nghiêm trọng vì Twig sẽ trả lại kết thúc trực tiếp và bỏ qua các đối số đã cho từ _context
là một mảng).
Một tiện ích Twig đơn giản đạt được mục đích này sẽ trông giống như thế này cho Symfony 2.8+. (Đối với Symfony 4, xem new documentation)
// src/AppBundle/Twig/Extension/CoreExtensions.php
namespace AppBundle\Twig\Extension;
class CoreExtensions extends \Twig_Extension
{
public function getFunctions()
{
return [
new \Twig_SimpleFunction('execute', [$this, 'executeClosure'])
];
}
public function executeClosure(\Closure $closure, $arguments)
{
return $closure(...$arguments);
}
public function getName()
{
return 'core_extensions_twig_extension';
}
}
Sau đó, trong các mẫu của bạn, bạn chỉ cần phải gọi thực hiện:
{{ execute(closure, [argument1, argument2]) }}
Nếu không kéo dài cành, một cách để có được xung quanh vấn đề này là sử dụng một lớp đóng vai trò như một trình bao bọc cho việc đóng của bạn và sử dụng hàm attribute
của Twig vì nó có thể được sử dụng để gọi một phương thức của một đối tượng.
// src/AppBundle/Twig/ClosureWrapper.php
namespace AppBundle\Twig;
/**
* Wrapper to get around the issue of not being able to use closures in Twig
* Since it is possible to call a method of a given object in Twig via "attribute",
* the only purpose of this class is to store the closure and give a method to execute it
*/
class ClosureWrapper
{
private $closure;
public function __construct($closure)
{
$this->closure = $closure;
}
public function execute()
{
return ($this->closure)(...func_get_args());
}
}
Sau đó, bạn chỉ cần cho một trường hợp ClosureWrapper cho mẫu của bạn khi vẽ thay vì việc đóng cửa chính nó:
use AppBundle\Twig\ClosureWrapper;
class MyController extends Controller
{
public function myAction()
{
$localValue = 2;
$closure = new ClosureWrapper(function($param1, $param2) use ($localValue) {
return $localValue + $param1 + $param2;
});
return $this->render('mytemplate.html.twig', ['closure' => $closure]);
}
...
Cuối cùng, trong mẫu của bạn, bạn cần phải sử dụng attribute
để thực hiện việc đóng cửa bạn định nghĩa trong điều khiển của bạn:
// Displays 12
{{ attribute(closure, 'execute', [4, 6]) }}
Tuy nhiên, đây là một chút dư thừa như, internally, các attribute
chức năng của Twig cũng giải thích các đối số đã cho. Bằng cách sử dụng mã trên, đối với mỗi cuộc gọi, các đối số được giải nén liên tục, đóng gói và giải nén lại.
Cảm ơn! Nhưng giải pháp này không làm việc cho tôi vì logic là biến số – Carles
Bạn có ý nghĩa gì bởi "logic là biến"? – Terenoth
Có thể có nhiều hàm điều kiện khác nhau, với các điều kiện khác nhau. Tôi cho rằng đó không phải là hiệu quả để đặt nhiều phần mở rộng như các điều kiện khác nhau bởi vì nó sẽ giết hiệu suất trên khuôn mẫu rendering. – Carles