Nop多语言之绑定属性控制类型(AttributeControlType)详解

Nop多语言之绑定属性控制类型(AttributeControlType)详解

3758发表于2016-08-21

nop管理后台编辑商品时可以为每个商品增加多个属性,这种设计大大的提高的系统的可扩展性,这样可以自适应种类型的商品,而不用改数据库表结构,我们可以从下图中看到页面显示效果:

上图红框里面可以看有三个属性,我们可以看到这个属性的类型是不同的,第一个是选择时间,第二和第三个是下拉框选择。这是通过什么来实现的呢?

我们在后台设置时,每个属性会有一个字段表示属性的控制类型,如下图:


正是这个属性的控制类型,我们选择不同的类型,前台页面就会以同的形式的输入展示,在Nop里面这是一个枚举类型。

下面我们来看看它是的底层原理。

AttributeControlType在命名空间Nop.Core.Domain.Catalog里面。

AttributeControlType.cs:

namespace Nop.Core.Domain.Catalog
{
    /// <summary>
    /// Represents an attribute control type
    /// </summary>
    public enum AttributeControlType
    {
        /// <summary>
        /// Dropdown list
        /// </summary>
        DropdownList = 1,
        /// <summary>
        /// Radio list
        /// </summary>
        RadioList = 2,
        /// <summary>
        /// Checkboxes
        /// </summary>
        Checkboxes = 3,
        /// <summary>
        /// TextBox
        /// </summary>
        TextBox = 4,
        /// <summary>
        /// Multiline textbox
        /// </summary>
        MultilineTextbox = 10,
        /// <summary>
        /// Datepicker
        /// </summary>
        Datepicker = 20,
        /// <summary>
        /// File upload control
        /// </summary>
        FileUpload = 30,
        /// <summary>
        /// Color squares
        /// </summary>
        ColorSquares = 40,
        /// <summary>
        /// Image squares
        /// </summary>
        ImageSquares = 45,
        /// <summary>
        /// Read-only checkboxes
        /// </summary>
        ReadonlyCheckboxes = 50,
    }
}
依次对应下拉框,单选按钮......


Nop后台是用的UI框架Kendo UI,列表对应的是里面的kendoGrid组件。

下面我们来看看视图文件具体代码实现。

绑定属性控制类型(AttributeControlType)对应视图文件: 

\src\Presentation\Nop.Web\Administration\Views\Product\_CreateOrUpdate.ProductAttributes.cshtml:


采用是变量AttributeControlType来绑定下拉列表,AttributeControlType是结合razor语法动态定义的。


上面代码主要作用是通过拼接一段js代码,来定义一个js变量。

注意ps:

上面用了标签<text>,这样表示是一段文本不作Razor语法表达式解析,如果不用<text>把其内容包裹起来,会报错的。

不信的同学可以试试。

因为里面有花括号和一些特殊字符,而这些又正好是在Razor里面有意义的。我们知道在Razor视图里面要表示纯文本有两种方法

1、用“@:”开头(单行)

2、用<text>标签包裹(多行文本)


接下来我们查看一下页面显示在浏览器中的源码。

可以看到最终是一个json格式的数组。而这个数组的数据来源是通过调用AttributeControlType一扩展方法实现的。

Nop.Web.Framework.Extensions:


public static SelectList ToSelectList<TEnum>(this TEnum enumObj, 
            bool markCurrentAsSelected = true, int[] valuesToExclude = null) where TEnum : struct
{
	if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

	var localizationService = EngineContext.Current.Resolve<ILocalizationService>();
	var workContext = EngineContext.Current.Resolve<IWorkContext>();

	var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
				 where valuesToExclude == null || !valuesToExclude.Contains(Convert.ToInt32(enumValue))
				 select new { ID = Convert.ToInt32(enumValue), Name = enumValue.GetLocalizedEnum(localizationService, workContext) };
	object selectedValue = null;
	if (markCurrentAsSelected)
		selectedValue = Convert.ToInt32(enumObj);
	return new SelectList(values, "ID", "Name", selectedValue);
}
可以从上面代码看到,ToSelectList是一个泛型方法,里面调用了Enum.GetValues返回对应枚举的所有值,并结合本地化多言服务LocalizationService转化成对应的语言。


在表LocaleStringResource详细记录了每种语言变量对应值。

你可以通过下面的sql语句查询本例涉及到的“全部属性控制类型”:

SELECT * FROM LocaleStringResource a WHERE a.LanguageId=2 AND a.ResourceName LIKE 'Enums.%'

注意:

Nop中针对枚举的语言资源都以“Enums.”开头是为了区分是枚举变量。

我们从Nop.Services.Localization.LocalizationExtensions里面针对枚举的扩展方法GetLocalizedEnum也能明白这个规律。



小编蓝狐