Orchard模塊開發全接觸2:新建 ProductPart


一:創建 Part

1:項目引用 Orchard.Framework;

2:創建 Models 文件夾;

3:在 Models 文件夾下創建類 ProductPartRecord,如下:

public class ProductPartRecord : ContentPartRecord
{
    public virtual decimal UnitPrice { get; set; }
    public virtual string Sku { get; set; }

}

注意,為 virtual,因為 orchard 的 NHIBERNATE 需要這樣。

以及 ProductRecord:

public class ProductPart : ContentPart<ProductPartRecord>
{
    public decimal UnitPrice
    {
        get { return Record.UnitPrice; }
        set { Record.UnitPrice = value; }
    }

    public string Sku
    {
        get { return Record.Sku; }
        set { Record.Sku = value; }
    }
}

 

二:更新數據庫

更新數據庫,依賴於一個叫 Migrations 的類型,我們需要創建在 根目錄下,如下:

public class Migrations : DataMigrationImpl
{
    public int Create()
    {

        SchemaBuilder.CreateTable("ProductPartRecord", table => table
            // The following method will create an "Id" column for us and set it is the primary key for the table
            .ContentPartRecord()
            // Create a column named "UnitPrice" of type "decimal"
            .Column<decimal>("UnitPrice")
            // Create the "Sku" column and specify a maximum length of 50 characters
            .Column<string>("Sku", column => column.WithLength(50))
            );

        // Return the version that this feature will be after this method completes
        return 1;
    }
}

如果不知道 Migrations 的用法,可參考:Orchard之Module升級,現在,我們查詢數據庫:

image

可以看到代碼已經執行,然后,表 TMinji_Shop_ProductPartRecord 也已經被創建了。

image

 

三:創建 ProductPart

上面,我們創建了 ProductPart 這個類,但是還不夠,我們需要把這個類更新到 ContentPartDefinition 這個表中,並且,我們需要注明 ProductPart 是 attachable 的,即:需用用戶在后台附加(attach)ProductPart。

現在,我們繼續通過代碼來做到這一點,我們仍舊在 Migrations 中做,這回,我們首先要引入 Orchard.Core,然后增加下面的代碼:

image

編譯,刷新下后台,查看數據庫:

image

發現 version 為 2 了,並且,Settings_ContentPartDefinitionRecord 表多了行數據:

image

並且,進入后台

image

發現,多了:

image

Edit 之,發現為:

image

這正是我們的代碼所定義的。

 

四:添加 Driver

現在,我們 Content -> Content Types and Create new Type,取名為 Book,並且,選擇:Body, Comments, Product, Title, Autoroute, and Tags ,然后保存,然后,重復以上,添加 DVD。

當到了這個時候,如果我們去添加 book,我們會發現,並沒有看到 Price 和 SKU,它們在哪里呢?是的,我們還缺少一個 Driver,

Driver 類似於 MVC 控制器,但是它對 contentpart 負責。典型的,它有三個方法:一個用於 part 的前台顯式,一個用於后台 edit 模式下的顯式,一個用於處理用戶在保存 content item的時候(這個時候,part 被 attached)。

其返回值為 DriverResult,當然,大部分情況下,實際上返回為 ShapeResult(從 DriverResult 繼承)。ShapeResult 告訴 Orchard,Razor 模版如何 render part。

現在,創建之:

1:首先,創建 Drivers 目錄;

2:創建 ProductPartDriver:

using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TMinji.Shop.Models;

namespace TMinji.Shop.Drivers
{
    public class ProductPartDriver : ContentPartDriver<ProductPart>
    {

        protected override string Prefix
        {
            get { return "Product"; }
        }

        protected override DriverResult Editor(ProductPart part, dynamic shapeHelper)
        {
            return ContentShape("Parts_Product_Edit", () => shapeHelper
                .EditorTemplate(TemplateName: "Parts/Product", Model: part, Prefix: Prefix));
        }

        protected override DriverResult Editor(ProductPart part, IUpdateModel updater, dynamic shapeHelper)
        {
            updater.TryUpdateModel(part, Prefix, null, null);
            return Editor(part, shapeHelper);
        }

    }

}

現在,有必要對代碼進行一下說明:

1:當前的 Driver 有兩個方法,一個在顯示 ProductPart 的 editor 的時候被嗲用,一個在后台提交 editor 表單的時候被調用(含 updater 的那個方法)。

2:我們把我們的 shape 命名為 Parts_Product_Edit,這樣子,它的視圖就是 Views/EditorTemplates/parts/product.cshtml。

現在,不妨來添加這個視圖

@using System.Web.Mvc.Html
@model TMinji.Shop.Models.ProductPart
<fieldset>
    <legend>Product Fields</legend>

    <div class="editor-label">@Html.LabelFor(x => x.Sku)</div>
    <div class="editor-field">
        @Html.EditorFor(x => x.Sku)
        @Html.ValidationMessageFor(x => x.Sku)
    </div>
    <div class="hint">Enter the Stock Keeping Unit</div>

    <div class="editor-label">@Html.LabelFor(x => x.UnitPrice)</div>
    <div class="editor-field">
        @Html.EditorFor(x => x.UnitPrice)
        @Html.ValidationMessageFor(x => x.UnitPrice)
    </div>
    <div class="hint">Enter the sales price per unit</div>
</fieldset>

為了讓這個視圖能正確呈現,我們還需要就加入引用

System.Web
System.Web.Mvc
System.Web.WebPages

前者在 全局程序集 下,后兩者,則可以在 lib\aspnetmvc 下可以找到(順注:你一定知道這個 lib 就是哪個 lib)。

然后,我們根目錄還缺少一個 web.config,我建議你直接從 blog 那個模塊下面進行拷貝,(順注:我的 orchard 是 1.8 版本):

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <remove name="host"/>
      <remove name="pages"/>
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Ajax"/>
        <add namespace="System.Web.Mvc.Html"/>
        <add namespace="System.Web.Routing"/>
        <add namespace="System.Web.WebPages"/>
        <add namespace="System.Linq"/>
        <add namespace="System.Collections.Generic"/>
        <add namespace="Orchard.Mvc.Html"/>
      </namespaces>
    </pages>
  </system.web.webPages.razor>
  <system.web>
    <compilation targetFramework="4.5">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </assemblies>
    </compilation>
  </system.web>
</configuration>

然后,在根目錄下,在創建一個 Placement.info,

<Placement>
  <Place Parts_Product_Edit="Content:1" />
</Placement>

這是告訴 Orchard,請顯式在 Widget 的 Content 部位。

現在,我們可以看到:

image

 

五:添加 handler(持久化數據)

我們來添加下面的數據:

Books:

  • The Hobbit, $50, SKU-1001
  • Wizard's First Rule, $39, SKU-1002
  • The Hunger Games, $29, SKU-1003

DVDs:

  • Prometheus, $30, SKU-1004
  • The Shawshank Redemption, $25, SKU-1005
  • The Dark Knight, $20, SKU-1006

然后,保存成功,然后,我們打算修改這些數據,結果發現 Price 和 Sku 是空的,這是為什么呢?因為我們還沒有實現持久化哦。要讓 Orchard 持久化數據,我們需要:

1:創建 Handlers 文件夾;

2:添加 ProductPartHandler,如下:

public class ProductPartHandler : ContentHandler
{
    public ProductPartHandler(IRepository<ProductPartRecord> repository)
    {
        Filters.Add(StorageFilter.For(repository));
    }
}

現在,我們發現可以增刪數據了。去查查數據庫吧:

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM