phalcon: volt получает значение из массива, ключ которого берется из переменной

В phalcon templating engine volt (который похож на twig) вы можете получить все записи:

{% for product in products %}
    Name: {{ product.name }}
    Description: {{ product.description }}
    price: {{ product.price}}
{% endfor  %}

Итак, в моем сценарии я создаю грубый шаблон, который будет использоваться для разных моделей. В этом шаблоне я хотел добиться того, чтобы все столбцы в этом представлении не были жестко запрограммированы. Итак, я сохраняю столбцы, которые хотел показать, в массив (определенный в контроллере, переданный в представление):

$cols = ['name','description','price']

В представлении, чтобы отображались все столбцы:

{% for product in products %}
   {% for col in cols %}
       {{ col }}: {{ product.col }}
   {% endfor  %}
{% endfor  %}

Очевидно, это приведет к ошибке, потому что в продукте нет "col".

Есть ли какое-либо решение или альтернатива для этого?


person AzDesign    schedule 25.03.2014    source источник
comment
Я не думаю, что это возможно (пока). Но, к счастью, вы можете расширить Volt docs.phalconphp.com/ ru/1.2.6/reference/volt.html#extending-volt   -  person Gerben Jacobs    schedule 25.03.2014
comment
Я считаю, что это может помочь: ссылка. Я не проверял, поэтому не опубликовал ответ. Создайте функцию и передайте параметры, например: {% funcName({{product}}, {{col}}) %}   -  person gabrieloliveira    schedule 25.03.2014
comment
Спасибо, я смотрю документацию и все еще не понимаю, с чего начать. Я знаю, что мне нужно создать функцию, 1-й аргумент принимает массив, а 2-й аргумент в качестве его ключа возвращает значение, которое соответствует ключу в массиве. А вот куда вставлять код, нужно ли делать отдельный файл для пользовательского кода, я не знаю. Документация, показывающая другой пример без каких-либо разъяснений деталей...   -  person AzDesign    schedule 25.03.2014
comment
Посмотрите на этот docs.phalconphp.com/en/latest/reference/volt .html#id3. По сути, вам нужно изменить файл начальной загрузки, в котором регистрируются службы (например, здесь github.com/phalcon/invo/blob/master/public/index.php#L77)   -  person jodator    schedule 26.03.2014
comment
Разве вы не можете использовать для этого обобщенные имена полей? поскольку вы используете CRUD, и ваш шаблон выглядит одинаково, кажется, что вы можете использовать одни и те же имена полей в моделях.   -  person deb0rian    schedule 26.03.2014
comment
Просто любопытно, вы уже проверили phalcon-devtools? Существует CRUD-приложение, с помощью которого можно запустить такую ​​реализацию или, по крайней мере, послужить справочным материалом о том, как работать с моделями абстрактным образом.   -  person kbtz    schedule 26.03.2014
comment
Имена полей @Fratyr отличаются от каждой модели, этого делать нельзя. Я начал с devtools, теперь я собираюсь заменить все эти отдельные представления и контроллеры на один грубый контроллер и набор представлений. Мне удалось зарегистрировать пользовательскую функцию, но я застрял на передаче значения. Я действительно не понимаю, почему существуют $resolvedArgs и $exprArgs. Массив (1-й аргумент) и ключ (2-й аргумент), которые я передал этой функции, переданы неправильно (читаются как точное имя переменной, а не ее значения). я все еще возюсь с этим   -  person AzDesign    schedule 27.03.2014


Ответы (3)


Разочаровавшись в расширении volt, я нашел более простое решение:

  1. Преобразуйте объект модели в массив. В контроллере: $products->toArray()

  2. Просто в представлении отображать конкретное значение определенного ключа из массива: {{ product[key] }}

Проблема решена, хотя, поскольку теперь он не в форме объекта, я не могу получить доступ к свойству объекта, используя точку, например {{ product.some_field }}, вместо {{ product['some_field'] }}.

person AzDesign    schedule 27.03.2014

Вы должны использовать функцию readAttribute(): http://forum.phalconphp.com/discussion/1231/volt-access-to-object-property-using-variable

{{ product.readAttribute(col) }}
person Yvan    schedule 27.10.2014
comment
Совсем не работает. Сообщение об ошибке: Fatal error: Call to undefined method stdClass::readAttribute(). - person Haozhe Xie; 10.05.2015
comment
Если ошибка говорит stdClass, это явно означает, что вы не дали объект модели, так как в Phalcon все объекты наследуются от конструктора Phalcon\Mvc\Model. И исходный вопрос явно подразумевает это: fetch all records. - person Yvan; 11.05.2015
comment
Я унаследовал класс модели от Phalcon\Mvc\Model. И я использую Phalcon 2.0. - person Haozhe Xie; 12.05.2015
comment
Я очень сомневаюсь, что: github.com/phalcon /cphalcon/blob/2.0.0/phalcon/mvc/ => метод существует, и в описании ошибки у вас есть «stdClass», что означает, что вы выгружаете класс по умолчанию, а не объект Phalcon. Попробуйте {{ dump(product) }} в вольтах, и вы увидите, что это не объект Phalcon. - person Yvan; 13.05.2015
comment
Да, ты прав. Поскольку я получаю объект, используя {% set i18nCategoryName = courseCategory['courseCategoryName'] | json_decode %}. И я хочу получить атрибут {language} (является переменной) i18nCategoryName. Так что этот метод мне не подходит. - person Haozhe Xie; 13.05.2015
comment
Вы можете использовать defined в этом случае, возможно, это сработает так, как ожидалось: {% if i18nCategoryName.property is defined %} ... {% endif %} - person Yvan; 17.05.2015

Еще одно решение:

In app/config/service.php:

$di->set('volt', function($view, $di) {
    $volt = new VoltEngine($view, $di);
    $volt->setOptions(array(
        'compiledPath' => APP_PATH . 'cache/volt/'
    ));
    $compiler = $volt->getCompiler();
    // Add this filter
    $compiler->addFilter('getAttribute', function ($resolvedArgs, $exprArgs) {
        return vsprintf('%s->{%s}', explode(', ', $resolvedArgs));
    });

    return $volt;
}, true);

И теперь вы можете получить атрибут следующим образом:

product|getAttribute(key)
person Haozhe Xie    schedule 10.05.2015