如何在没有页面类型引用的块ajax调用中获取currentBlock。 [episerver 9]

时间:2016-05-29 13:31:25

标签: asp.net-ajax episerver episerver-8

在阻止ajax调用中获取currentBlock的最佳方法是什么?

[HttpGet]
public ActionResult GetSomething()
{
    var currentBlock = Get(); //how?
    return currentBlock.SomeLabel;
}

(当Block或BlockController不知道页面时,我不知道解决方案)

我想让任何页面都可以重复使用块。

感谢。

2 个答案:

答案 0 :(得分:2)

为什么不添加路线呢?因此,无论块使用何处,URL都相同?或者将操作放在所有页面控制器的基类中。 然后你必须将参考传递给你视图块中的动作。

答案 1 :(得分: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}.");
    }
}