سؤال

أرغب في إنشاء WebApplication مع "واجهة صفحة واحدة" ، باستخدام ASP.NET MVC.

لقد بحثت إذا كان هذا ممكنًا على الأقل وأعتقد أن الإجابة هي: ليس بوسائل بسيطة (القراءة http://msdn.microsoft.com/en-us/magazine/cc507641.aspx#s2 الفقرة ذات الأبقار الثانية ؛ هذا المقال من مايو 2008 ، رغم ذلك).

لقد وجدت أمثلة أخرى نفذت هذا عن طريق الترميز/القرصنة مع jQuery. ومع ذلك ، أنا أبحث عن حل نظيف ، باستخدام أساليب .NET القياسية ، إن أمكن.

ما أريده هو بالضبط نفس الوظيفة عند إنشاء "تطبيق ويب MVC" جديد. ومع ذلك ، بدلاً من الروابط بـ "/home/about" التي تعيد تحميل الصفحة بأكملها ، أريد روابط لـ "#الصفحة الرئيسية/حول "الذي يحمل الجزء الجديد فقط عبر AJAX.

النهج القياسي لمكالمة القوالب (طرق العرض الجزئية) مع html.renderpartial هو بالضبط ما أريده ، ثم فقط تحميلها من خلال jax-requests.

بالطبع ، قد يكون لا يمكنني استخدامه هؤلاء القوالب التي يتم تقديمها بواسطة الصفحة الرئيسية لسبب ما (ربما تتوقع أن يتم استدعاؤها دائمًا في سياق معين من مكان معين أو نحو ذلك). ولكن ربما يكون هناك حل نظيف آخر لكيفية إنشاء صفحات القالب الخاصة بك وجلبها من الصفحة الرئيسية.

من لديه حل لطيف لتنفيذ مثل هذا الشيء ، واجهة صفحة واحدة؟

ملاحظة: أنا أتطور في Visual Web Developer 2008 Express Edition مع تثبيت MVC 1.0 ، في C#

تعديلفيما يلي قرأت أن العمل مع القوالب أمر ممكن وأن jQuery يبدو وكأنه أمر لا مفر منه ، لذلك اختبرته. يحول الكود التالي الروابط العادية التي تم إنشاؤها بواسطة html.actionlink إلى روابط مرساة (مع #) لاحتواء السجل ، ثم إحضار الصفحة عبر Ajax وحقن جزء HTML فقط (أي الصفحة الجزئية داخل Div # نظرة جزئية):

$("a").each(function() {
    $(this).click(function() {
        $("div#partialView").load($(this).attr("href") + " div#partialView");
        location.hash = $(this).attr("href");
        return false;
    });
});

هذه الروابط تسمح أيضًا بالتخلي عن رشيقة.

لكن ما تركته الآن ، ما زال يجلب كامل الصفحة بدلاً من الصفحة الجزئية فقط. تغيير وحدة التحكم لم يساعد ؛ ما زال يوفر لي HTML من الصفحة بأكملها ، مع كل هذه العبارات:

public ActionResult About()
{
    return View();
    return View("About");
    return PartialView();
    return PartialView("About");
}

كيف يمكنني إعادة محتوى الجزء الذي يهتم به فقط (أي محتويات المنزل/about.aspx)؟ ما أحب هو نشر قيمة مع Ajax (على سبيل المثال "requesttype = ajax") بحيث تعرف وحدة التحكم الخاصة بي أن الصفحة تم جلبها عبر Ajax وإرجاع الصفحة الجزئية فقط ؛ وإلا فإنه سيعيد الصفحة بأكملها (أي عند زيارتك/الصفحة الرئيسية/بدلاً من #الصفحة الرئيسية/حول).

هل الممارسة الجيدة لتغيير Global.asax.cs ربما ، لإنشاء مخطط توجيه جديد لـ Ajax-Calls ، والتي ستعيد فقط الصفحات الجزئية؟ (لم أنظر إلى هذا كثيرًا ، حتى الآن.)

EDIT2كان روبرت كوريتنيك على حق: كنت بحاجة أيضًا إلى صفحة حول. ASCX (USERCONTROL) مع فقط محتوى HTML الصغير لتلك الصفحة. تم ربط السطر الأول من ound.aspx مع الصفحة الرئيسية عبر MasterPageFile="~/..../Site.master" مما تسبب في طباعة جميع HTML.

ولكن لكي تكون قادرًا على تنفيذ ما يلي في وحدة التحكم الخاصة بي:

public ActionResult About()
{
    return Request.IsAjaxRequest() ? (ActionResult)PartialView() : View();
}

كنت بحاجة لتغيير طريقة أ PartialView (ملف .ascx) و View تم العثور على ملف (.aspx) ، وإلا فإن كلتا الطريقتين ستعيد نفس الصفحة (About.aspx, ، مما أدى في النهاية إلى حلقة لا حصر لها). بعد وضع ما يلي Global.asax.cs, ، سيتم إرجاع الصفحات الصحيحة مع PartialView() و View():

protected void Application_Start()
{
    foreach (WebFormViewEngine engine in ViewEngines.Engines.Where(c => c is WebFormViewEngine))
    {
        /* Normal search order:
        new string[] { "~/Views/{1}/{0}.aspx",
            "~/Views/{1}/{0}.ascx",
            "~/Views/Shared/{0}.aspx"
            "~/Views/Shared/{0}.ascx"
        };
        */

        // PartialViews match with .ascx files
        engine.PartialViewLocationFormats = new string[] { "~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx" };

        // Views match with .aspx files
        engine.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };
    }

    RegisterRoutes(RouteTable.Routes);
}
هل كانت مفيدة؟

المحلول

عرض كامل مقابل عرض جزئي

يبدو أنك أفسدت شيئًا. إذا قمت بإنشاء About.aspx صفحة مع جميع HTML اللازمة لعرض الصفحة بأكملها لا يهم حقًا إذا قلت

return PartialView('About');

لا يزال العرض يعيد جميع HTML المكتوبة فيه.

يجب عليك إنشاء منفصلة About.ascx لن يكون لهذا سوى محتوى الصفحة نفسها بدون الرأس والأشياء الأخرى التي تشكل جزءًا من الصفحة بأكملها.

صفحتك الأصلية About.aspx سيكون لديك شيء من هذا القبيل في محتواه (لتجنب تكرار كتابة نفس المحتوى مرتين):

<%= Html.RenderPartial("About") %>

ويمكن أن يكون لديك اثنين من إجراءات وحدة التحكم. واحد يعيد عرضًا منتظمًا ويعيد عرضًا جزئيًا:

return View("About"); // returns About.aspx that holds the content of the About.ascx as well
return PartialView("About"); // only returns the partial About.ascx

بخصوص الطرق في Global.asax

بدلاً من كتابة طرق منفصلة لمكالمات AJAX ، تفضل كتابة مرشح إجراء يعمل على غرار AcceptVerbsAttribute فلتر العمل. وبهذه الطريقة ، ستبقى طلباتك من العميل كما هي (وبالتالي منع المستخدم من طلب الأشياء الخاطئة يدويًا) ، ولكن بناءً على نوع الطلب ، سيتم تنفيذ إجراء وحدة التحكم الصحيح.

نصائح أخرى

حسنًا ، يمكنك تحميل عرض جزئي من خلال طلب Ajax. على سبيل المثال ، سأستخدم jQuery لإجراء مكالمة Ajax.

يمكن أن يكون هذا هو الإجراء في وحدة التحكم (المسماة HomeController):

public ActionResult About()
    {
        //Do some logic...
        //AboutView is the name of your partial view
        return View("AboutView");
    }

اتصل بـ jQuery Ajax لوضع HTML المحددة في المكان الذي تريده:

var resultDiv = $('#contentDIV');

    $.ajax({
        type: "POST",
        url: "/Home/About",
        success: function(responseHTML) {
            resultDiv.replaceWith(responseHTML);
        }
    });

تم تحديث relection question

من الممكن أن تفعل بالضبط ما تريد. يمكن أن يعيدك أول إجراء وحدة تحكم العرض الجزئي ، لذلك كان من الممكن أن يكون "AboutView" شيء من هذا القبيل:

<table>
<tr>
    <th>
        Column1Header
    </th>
    <th>
        Column2Header
    </th>
</tr>
<tr>
    <td>
    ...
    </td>
    <td>
    ...
    </td>
</tr>

وهذا HTML هو بالضبط ما ستحصل عليه في الرد على معالج النجاح في طريقة jQuery Ajax.

ثانياً ، يمكنك التمييز في إجراء وحدة التحكم إذا كان الطلب هو طلب AJAX:

public ActionResult About()
    {
        //partial AboutView is returned if request is ajax
        if (Request.IsAjaxRequest())
            return View("AboutView");
        else //else it will be the default view (page) for this action: "About"
            return View();
    }

لدينا موقع يقوم بذلك بالضبط ، وتريد حقًا استخدام مسار jQuery هنا-أسهل في التنفيذ على المدى الطويل. ويمكنك بسهولة جعلها تتحلل بأمان بالنسبة للمستخدمين الذين لم يتم تمكين JavaScript-مثل Google.

ليس من الواضح ما الذي تطلبه ، هل هو مثال كامل أو لبعض الوظائف المحددة؟ يجب أن تكون قادرًا على القيام بذلك دون jQuery لسيناريوهات بسيطة ، يمكنك استخدام مساعدي Ajax View مثل طريقة ActionLink. أيضًا ، لا أفهم حقًا ما هي مشكلتك في Renderpartial ، ولكن ربما كنت تبحث عن شيء مثل RenderAction من ASP.NET MVC Futures.

يضيف ASP.NET MVC 4 (الآن في بيتا) دعمًا لتطبيقات الصفحة الفردية في MVC.

http://www.asp.net/single-page-application

تحديث: ... وأزالوه من MVC 4 RC

تحديث: ... وعاد مع تحديث فال 2012

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top