Add IUriHelper.NavigateTo

This commit is contained in:
Steve Sanderson 2018-03-16 11:19:09 +00:00
parent cb473e8ad7
commit d0731c337d
5 changed files with 52 additions and 5 deletions

View File

@ -1,6 +1,6 @@
import { registerFunction } from '../Interop/RegisteredFunction';
import { platform } from '../Environment';
import { MethodHandle } from '../Platform/Platform';
import { MethodHandle, System_String } from '../Platform/Platform';
const registeredFunctionPrefix = 'Microsoft.AspNetCore.Blazor.Browser.Services.BrowserUriHelper';
let notifyLocationChangedMethod: MethodHandle;
let hasRegisteredEventListeners = false;
@ -24,8 +24,7 @@ registerFunction(`${registeredFunctionPrefix}.enableNavigationInteception`, () =
const href = anchorTarget.getAttribute('href');
if (isWithinBaseUriSpace(toAbsoluteUri(href))) {
event.preventDefault();
history.pushState(null, /* ignored title */ '', href);
handleInternalNavigation();
performInternalNavigation(href);
}
}
});
@ -33,6 +32,20 @@ registerFunction(`${registeredFunctionPrefix}.enableNavigationInteception`, () =
window.addEventListener('popstate', handleInternalNavigation);
});
registerFunction(`${registeredFunctionPrefix}.navigateTo`, (uriDotNetString: System_String) => {
const href = platform.toJavaScriptString(uriDotNetString);
if (isWithinBaseUriSpace(toAbsoluteUri(href))) {
performInternalNavigation(href);
} else {
location.href = href;
}
});
function performInternalNavigation(href: string) {
history.pushState(null, /* ignored title */ '', href);
handleInternalNavigation();
}
function handleInternalNavigation() {
if (!notifyLocationChangedMethod) {
notifyLocationChangedMethod = platform.findMethod(

View File

@ -104,6 +104,17 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Services
throw new ArgumentException($"The URI '{absoluteUri}' is not contained by the base URI '{baseUriPrefix}'.");
}
/// <inheritdoc />
public void NavigateTo(string uri)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
RegisteredFunction.InvokeUnmarshalled<object>($"{_functionPrefix}.navigateTo", uri);
}
private static void EnsureBaseUriPopulated()
{
// The <base href> is fixed for the lifetime of the page, so just cache it

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Blazor.Services
/// <summary>
/// Gets the current absolute URI.
/// </summary>
/// <returns>The browser's current absolute URI.</returns>
/// <returns>The current absolute URI.</returns>
string GetAbsoluteUri();
/// <summary>
@ -44,5 +44,12 @@ namespace Microsoft.AspNetCore.Blazor.Services
/// <param name="absoluteUri">An absolute URI that is within the space of the base URI prefix.</param>
/// <returns>A relative URI path.</returns>
string ToBaseRelativePath(string baseUriPrefix, string locationAbsolute);
/// <summary>
/// Navigates to the specified URI.
/// </summary>
/// <param name="uri">The destination URI. This can be absolute, or relative to the base URI
/// prefix (as returned by <see cref="GetBaseUriPrefix"/>).</param>
void NavigateTo(string uri);
}
}

View File

@ -110,6 +110,16 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests
Assert.Equal("This is the default page.", app.FindElement(By.Id("test-info")).Text);
}
[Fact]
public void CanNavigateProgrammatically()
{
SetUrlViaPushState($"{ServerPathBase}/RouterTest/");
var app = MountTestComponent<TestRouter>();
app.FindElement(By.TagName("button")).Click();
Assert.Equal("This is another page.", app.FindElement(By.Id("test-info")).Text);
}
public void Dispose()
{
// Clear any existing state

View File

@ -1,4 +1,6 @@
<ul>
@inject Microsoft.AspNetCore.Blazor.Services.IUriHelper uriHelper
<ul>
<li><a href="/subdir/RouterTest/">Default</a></li>
<li><a href="/subdir/RouterTest/?abc=123">Default with query</a></li>
<li><a href="/subdir/RouterTest/#blah">Default with hash</a></li>
@ -7,3 +9,7 @@
<li><a href="/subdir/RouterTest/Other?abc=123">Other with query</a></li>
<li><a href="/subdir/RouterTest/Other#blah">Other with hash</a></li>
</ul>
<button onclick=@{ uriHelper.NavigateTo("RouterTest/Other"); }>
Programmatic navigation
</button>