因此,我遇到了一些问题,用最好的惯用方法来灵活地使用Mustache.php处理一些复杂的html案例。
第一个是预选的选择下拉列表。
<select>
<option value=''></option>
<option value='bob'>Bob Williams</option>
<option value='james' selected>James Smith</option>
</select>我有办法处理这件事,但我的方式似乎很死板:
是否有一种很棒的方法,可以使用部分或匿名函数或方法或我缺少的mustache.php的其他特性来进行预选选择下拉列表?
编辑:将这个问题分割成不同的部分,以最大限度地提高清晰度。
发布于 2012-10-05 19:47:26
在胡子中这样做的惯用方法是创建一个视图(或ViewModel),而不是传递数据散列:
<?php
class Dropdown
{
public $name;
public $value;
private $options;
public function __construct($name, array $options, $value)
{
$this->name = $name;
$this->options = $options;
$this->value = $value;
}
public function options()
{
$value = $this->value;
return array_map(function($k, $v) use ($value) {
return array(
'value' => $k,
'display' => $v,
'selected' => ($value === $k),
)
}, array_keys($this->options), $this->options);
}
}然后你可以把它和dropdown部分结合起来..。
<select name="{{ name }}">
{{# options }}
<option value="{{ value }}"{{# selected }} selected{{/ selected }}>
{{ display }}
</option>
{{/ options }}
</select>您可以在模板中使用如下所示:
{{# state }}
<label for="{{ name }}">State</label>
{{> dropdown }}
{{/ state }}
{{# country }}
<label for="{{ name }}">Country</label>
{{> dropdown }}
{{/ country }}并使之:
<?php
$data = array(
'state' => new Dropdown('state', $someListOfStates, 'CA'),
'country' => new Dropdown('country', $someListOfCountries, 'USA'),
);
$template->render($data);..。但你可以做得更好:)
在这方面:
<?php
class StateDropdown extends Dropdown
{
static $states = array(...);
public function __construct($value, $name = 'state')
{
parent::__construct($name, self::$states, $value);
}
}这是:
<?php
class CountryDropdown extends Dropdown
{
static $countries = array(...);
public function __construct($value, $name = 'country')
{
parent::__construct($name, self::$countries, $value);
}
}其中之一是:
<?php
class Address
{
public $street;
public $city;
public $state;
public $zip;
public $country;
public function __construct($street, $city, $state, $zip, $country, $name = 'address')
{
$this->street = $street;
$this->city = $city;
$this->state = new StateDropdown($state, sprintf('%s[state]', $name));
$this->zip = $zip;
$this->country = new CountryDropdown($country, sprintf('%s[country]', $name));
}
}加入一个新的address部分:
<label for="{{ name }}[street]">Street</label>
<input type="text" name="{{ name }}[street]" value="{{ street }}">
<label for="{{ name }}[city]">City</label>
<input type="text" name="{{ name }}[city]" value="{{ city }}">
{{# state }}
<label for="{{ name }}">State</label>
{{> dropdown }}
{{/ state }}
<label for="{{ name }}[zip]">Postal code</label>
<input type="text" name="{{ name }}[zip]" value="{{ zip }}">
{{# country }}
<label for="{{ name }}">Country</label>
{{> dropdown }}
{{/ country }}更新您的主模板:
<h2>Shipping Address</h2>
{{# shippingAddress }}
{{> address }}
{{/ shippingAddress }}
<h2>Billing Address</h2>
{{# billingAddress }}
{{> address }}
{{/ billingAddress }}快走!
<?php
$data = array(
'shippingAddress' => new Address($shipStreet, $shipCity, $shipState, $shipZip, $shipCountry, 'shipping'),
'billingAddress' => new Address($billStreet, $billCity, $billState, $billZip, $billCountry, 'billing'),
};
$template->render($data);现在,您可以使用模块化的、可重用的、易于测试的、可扩展的代码和部分代码。
注意,我们创建的类是“视图”或"ViewModels“。它们不是你的领域模型对象..。他们不关心持久化或验证,他们只关心为模板准备值。如果您也使用模型,这将使它更加容易,因为像Address类这样的东西可以包装您的地址模型,并直接从模型中获取它所需要的值,而不是要求您将一堆东西传递给构造函数。
胡子的禅宗
如果您采用这种方法来得出其逻辑结论,那么您的应用程序ViewModel View中的每个动作/模板对将得到一个顶级视图或- the类,可以在内部委托给子视图和部分视图,就像我们在地址视图中的下拉列表一样,但是您将有一个第一级视图或ViewModel负责呈现每个操作。
这意味着(在MVC/MVVM世界中),Controller操作将执行任何需要它的“操作”,然后创建负责填充模板的视图或ViewModel类,向它传递几个域模型对象,并对模板调用呈现。Controller不会准备任何数据,因为这是视图层的责任。它只需将几个模型对象交给它。
现在,所有用于“呈现”的逻辑都整齐地封装在视图层中,您的所有标记都整齐地封装在模板文件中,您的模型没有丑陋的格式化业务,并且您的Controller很好,而且很轻,就像它应该的那样:)
发布于 2014-02-28 16:48:53
bobthecow是一个很好的起点,但是代码中有一些错误。
我必须更改下拉类以支持kohana中的多选择下拉列表,array_map要求您将相同数量的变量传递给函数。
下课:
class Tiaa_Dropdown
{
public $name;
public $value;
private $options;
public function __construct($name, array $options, $value)
{
$this->nameAttr = $name;
$this->options = $options;
$this->value = $value;
}
public function things()
{
$value = $this->value;
$array_keys = array_keys($this->options);
$array_values = array_values($this->options);
return array_map(function($k, $v) use ($value) {
if(is_array($value)) {
$selected = (in_array($k, $value) ? 1 : 0);
} else {
$selected = ($value == $k);
}
return array(
'value' => $k,
'display' => $v,
'selected' => $selected
);
}, $array_keys, $array_values);
}
} // End希望这能帮上忙。
https://stackoverflow.com/questions/12358228
复制相似问题