2016-05-29 29 views

回答

2

我认为你必须传递块的内容引用,但这并不是那么糟糕。

首先,确保你的global.asax类包括在覆盖的RegisterRoutes方法标准的MVC路线:

public class EPiServerApplication : EPiServer.Global 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
    } 

    protected override void RegisterRoutes(RouteCollection routes) 
    { 
     base.RegisterRoutes(routes); 

     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { action = "Index", id = UrlParameter.Optional }); 
    } 
} 

我有我用于测试一些东西出来一个块;它有一个Title属性和Items - 一个内容引用列表。

[ContentType(DisplayName = "Super Happy Fun Block", GUID = "b5d5c00c-dc8e-4ada-8319-20fd3474d4e7", Description = "")] 
public class SuperHappyFunBlock : BlockData 
{ 
    public virtual string Title { get; set; } 

    public virtual IList<ContentReference> Items { get; set; } 
} 

对于此块中,我创建一个包含这些特性加上ContentReference属性视图模型。你可以在你的cshtml视图文件中做到这一点,但这会让你的视图更清晰一些。

public class SuperHappyFunModel 
{ 
    public string Title { get; set; } 

    public IList<ContentReference> Items { get; set; } 

    public ContentReference ContentLink { get; set; } 
} 

接着,电线了块的控制器使用的视图模式。我也需要一些JavaScript文件;这些可以通过控制器添加到这里。有关更多信息,请参阅Client Resources上的Episerver文档。

public class SuperHappyFunBlockController : BlockController<SuperHappyFunBlock> 
{ 
    public override ActionResult Index(SuperHappyFunBlock currentBlock) 
    { 
     ClientResources.RequireScript("https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js").AtFooter(); 
     ClientResources.RequireScript("/static/js/SuperHappyFunBlock.js").AtFooter(); 

     var model = new SuperHappyFunModel 
     { 
      Title = currentBlock.Title, 
      Items = currentBlock.Items, 
      ContentLink = (currentBlock as IContent)?.ContentLink ?? ContentReference.EmptyReference 
     }; 

     return PartialView(model); 
    } 
} 

在视图,确保内容被引用在一个地方的JavaScript可以找到它呈现。我将使用名为data-block-id的数据属性。

@model SuperHappyFunModel 

<div class="SuperHappyFunBlockController" data-block-id="@Model.ContentLink.ToString()"> 
    <p class="dynamic">Content goes here.</p> 
</div> 

块中的控制器所引用的JavaScript文件将需要寻找网页上的所有块实例,然后为每一个,使Ajax调用。请记住,如果您的块在页面上用作属性,那么它将不会有ContentLink,因为块属性不会继承IContent

(function($) { 
    $('.SuperHappyFunBlockController') 
     .each(function (index, blockDiv) { 
      var $blockDiv = $(blockDiv), 
       blockId = $blockDiv.attr('data-block-id'); 
      if (!blockId) { 
       console.log('This block must be a property on a page... no block id found!'); 
       return; 
      } 
      $.ajax({ 
       method: 'GET', 
       url: '/superhappyfunblock/getsomething/' + blockId, 
       success: function (data) { 
        console.log(data); 
        $blockDiv.find('.dynamic').text(data); 
       } 
      }); 
      console.log(blockId); 
     }); 
})($); 

最后,做的最后一件事是创建控制器上的AJAX方法。这将期望一个名为“id”的字符串参数,以便它符合我们在开始时添加的默认MVC视图。它也将在控制器上使用依赖注入来获得IContentLoader的实例。

public class SuperHappyFunBlockController : BlockController<SuperHappyFunBlock> 
{ 
    public override ActionResult Index(SuperHappyFunBlock currentBlock) 
    { 
     // code omitted here for brevity... 
    } 

    private readonly IContentLoader _contentLoader; 

    public SuperHappyFunBlockController(IContentLoader contentLoader) 
    { 
     _contentLoader = contentLoader; 
    } 

    public ActionResult GetSomething(string id) 
    { 
     ContentReference blockReference; 
     if (!ContentReference.TryParse(id, out blockReference)) 
      return HttpNotFound(); 

     SuperHappyFunBlock block; 
     if (!_contentLoader.TryGet(blockReference, out block)) 
      return HttpNotFound(); 

     return Content($"This is some really cool stuff for the block named {((IContent) block).Name}."); 
    } 
} 
2

为什么不添加路线呢?所以无论使用哪个块,URL都是一样的?或者把所有的页面控制器放在基类中。 然后你必须从你的块的视图中传递参考。

+1

我认为约翰的建议是好的,但你也可以通过** ** PageRouteHelper类帮助获取当前页面上下文:http://world.episerver.com/documentation/class-库/?documentId = CMS/8/AB460229 –

相关问题