From 2ac23218f076d4705b341a485b9d24d03b6f0570 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 9 Apr 2020 14:59:18 +0300 Subject: [PATCH 01/65] docs: add @ngxs/cli to generate state files instead of ngxs-schematic --- docs/en/Tutorials/Part-1.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/en/Tutorials/Part-1.md b/docs/en/Tutorials/Part-1.md index 20b64f3189..a32bf8d8a9 100644 --- a/docs/en/Tutorials/Part-1.md +++ b/docs/en/Tutorials/Part-1.md @@ -877,10 +877,29 @@ Run the following command in the terminal to create a new state, named `BooksSta ![Initial book list page](./images/bookstore-generate-state-books.png) ```bash -yarn ng generate ngxs-schematic:state books +npx @ngxs/cli --name books --directory src/app/books ``` -* This command creates several new files and updates `app.modules.ts` file to import the `NgxsModule` with the new state. +* This command creates books.state.ts and books.actions.ts files in the `src/app/books/state` folder. See the [NGXS CLI documentation](https://www.ngxs.io/plugins/cli). + +Import the `BooksState` to the `app.module.ts` in the `src/app` folder and then add the `BooksState` to `forRoot` static method of `NgxsModule` as an array element of the first parameter of the method. + +```js +// ... +import { BooksState } from './books/state/books.state'; //<== imported BooksState ==> + +@NgModule({ + imports: [ + // other imports + + NgxsModule.forRoot([BooksState]), //<== added BooksState ==> + + //other imports + ], + // ... +}) +export class AppModule {} +``` #### Get books data from backend From 90a4befd307ef227a878f64c61b841b43170a258 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 16 Apr 2020 20:59:46 +0800 Subject: [PATCH 02/65] Redirect to home page when an invalid URL or missing document --- .../Pages/Documents/Project/Index.cshtml.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 56f9dac913..7c45cf0ae0 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -9,11 +9,8 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Volo.Abp; -using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; using Volo.Abp.Domain.Entities; -using Volo.Abp.Localization; using Volo.Docs.Documents; using Volo.Docs.HtmlConverting; using Volo.Docs.Models; @@ -103,7 +100,9 @@ namespace Volo.Docs.Pages.Documents.Project Logger.LogWarning(exception.Message); DocumentFound = false; - return Page(); + var url = DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/" + + (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version); + return Redirect(url); } } @@ -120,7 +119,7 @@ namespace Volo.Docs.Pages.Documents.Project catch (EntityNotFoundException e) { Logger.LogWarning(e.Message); - return NotFound(); + return Redirect(DocumentsUrlPrefix); } if (ShowProjectsCombobox) From f8b314f4abad2ee276f720ce785c575da819ebf6 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 17 Apr 2020 22:05:34 +0800 Subject: [PATCH 03/65] Show error and redirect when project or document not found --- .../Volo/Docs/Localization/Domain/en.json | 1 + .../Docs/Localization/Domain/zh-Hans.json | 3 +- .../Pages/Documents/Project/Index.cshtml | 38 +++++++++++++------ .../Pages/Documents/Project/Index.cshtml.cs | 17 +++++++-- .../Pages/Documents/Project/index.js | 31 +++++++++++---- .../DocumentNotFoundPageModel.cs | 15 -------- .../DocumentNotFoundViewComponent.cs | 26 ------------- .../Default.cshtml | 11 +++--- .../Shared/ErrorComponent/ErrorPageModel.cs | 11 ++++++ .../ErrorComponent/ErrorViewComponent.cs | 14 +++++++ 10 files changed, 96 insertions(+), 71 deletions(-) delete mode 100644 modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundPageModel.cs delete mode 100644 modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundViewComponent.cs rename modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/{DocumentNotFoundComponent => ErrorComponent}/Default.cshtml (62%) create mode 100644 modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorPageModel.cs create mode 100644 modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorViewComponent.cs diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json index 6299a9aab2..fef9102118 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json @@ -14,6 +14,7 @@ "Projects": "Project(s)", "NoProjectWarning": "There are no projects yet!", "DocumentNotFound": "Oops, the requested document was not found!", + "ProjectNotFound": "Oops, the requested project was not found!", "NavigationDocumentNotFound": "This version does not have a navigation document!", "DocumentNotFoundInSelectedLanguage": "Document in the language you wanted is not found. Document in the default language is shown.", "FilterTopics": "Filter topics", diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json index ef4e95f3dc..761e28c1bb 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json @@ -1,6 +1,6 @@ { "culture": "zh-Hans", - "texts": { + "texts": { "Documents": "文档", "BackToWebsite": "返回主网站", "Contributors": "贡献者", @@ -14,6 +14,7 @@ "Projects": "项目", "NoProjectWarning": "还没有项目!", "DocumentNotFound": "找不到请求的文档!", + "ProjectNotFound": "找不到請求的項目!", "NavigationDocumentNotFound": "这个版本没有导航文件!", "DocumentNotFoundInSelectedLanguage": "本文档不适用于所选语言, 将以默认语言显示文档.", "FilterTopics": "过滤主题", diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index b7db40f1fe..fa1659ab54 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -5,12 +5,12 @@ @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard @using Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper -@using Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs @using Volo.Abp.AspNetCore.Mvc.UI.Theming @using Volo.Docs @using Volo.Docs.Localization @using Volo.Docs.Pages.Documents.Project +@using Volo.Docs.Pages.Documents.Shared.ErrorComponent @inject IThemeManager ThemeManager @inject IPageLayout PageLayout @inject IHtmlLocalizer L @@ -41,7 +41,7 @@ } -@if (Model.DocumentFound) +@if (Model.LoadSuccess) {
@@ -348,14 +348,30 @@ } else { - @(await Component.InvokeAsync(new - { - model = new DocumentNotFoundPageModel + if (!Model.DocumentFound) + { + @(await Component.InvokeAsync(new { - ProjectName = Model.ProjectName, - DocumentName = Model.DocumentName, - LanguageCode = Model.LanguageCode, - Version = Model.Version, - } - })) + model = new ErrorPageModel + { + RedirectUrl = Model.DocumentsUrlPrefix + Model.LanguageCode + "/" + Model.ProjectName + "/" + + (Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version), + ErrorCode = "404", + ErrorMessage = L.GetString("DocumentNotFound") + } + })) + } + if (!Model.EntityFound) + { + @(await Component.InvokeAsync(new + { + model = new ErrorPageModel + { + RedirectUrl = Model.DocumentsUrlPrefix, + ErrorCode = "404", + ErrorMessage = L.GetString("ProjectNotFound") + } + })) + } + } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 7c45cf0ae0..8d10d876a8 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using System.Web; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; @@ -33,6 +34,10 @@ namespace Volo.Docs.Pages.Documents.Project public string LanguageCode { get; set; } public bool DocumentFound { get; set; } = true; + + public bool EntityFound { get; set; } = true; + + public bool LoadSuccess => DocumentFound && EntityFound; public string DefaultLanguageCode { get; set; } @@ -100,9 +105,7 @@ namespace Volo.Docs.Pages.Documents.Project Logger.LogWarning(exception.Message); DocumentFound = false; - var url = DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/" - + (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version); - return Redirect(url); + return Page(); } } @@ -119,7 +122,8 @@ namespace Volo.Docs.Pages.Documents.Project catch (EntityNotFoundException e) { Logger.LogWarning(e.Message); - return Redirect(DocumentsUrlPrefix); + EntityFound = false; + return Page(); } if (ShowProjectsCombobox) @@ -596,6 +600,11 @@ namespace Volo.Docs.Pages.Documents.Project public string GetDescription() { + if (Document == null || Document.Content.IsNullOrWhiteSpace()) + { + return null; + } + var firstParagraph = new Regex(@"

(.*?)

", RegexOptions.IgnoreCase); var match = firstParagraph.Match(Document.Content); if (!match.Success) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 1b3d5ac7c3..d85b5a8630 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -297,17 +297,32 @@ $("#crawler_link").html(html); }; - initNavigationFilter("sidebar-scroll"); - - initAnchorTags(".docs-page .docs-body"); + var errorPageRedirect = function(){ + var second = 3; + var close = setInterval(()=>{ + second--; + $(".seconds").text(`(${second})`) + if(second===0){ + clearInterval(close); + $(".redirect")[0].click(); + } + },1000) + } + + var loadSuccess = $(".docs-page").length!==0; + if(loadSuccess === true){ + initNavigationFilter("sidebar-scroll"); - initSocialShareLinks(); + initAnchorTags(".docs-page .docs-body"); - initSections(); + initSocialShareLinks(); - initCrawlerLinks(); + initSections(); + initCrawlerLinks(); + }else{ + errorPageRedirect(); + } }); -})(jQuery); - +})(jQuery); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundPageModel.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundPageModel.cs deleted file mode 100644 index 72b2b97584..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundPageModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent -{ - public class DocumentNotFoundPageModel - { - public string ProjectName { get; set; } - - public string LanguageCode { get; set; } - - public string Version { get; set; } - - public string DocumentName { get; set; } - - public string DocumentsUrlPrefix { get; set; } - } -} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundViewComponent.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundViewComponent.cs deleted file mode 100644 index 7aeed9beee..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/DocumentNotFoundViewComponent.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; -using Volo.Abp.AspNetCore.Mvc; - -namespace Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent -{ - public class DocumentNotFoundViewComponent : AbpViewComponent - { - private readonly DocsUiOptions _options; - - public DocumentNotFoundViewComponent(IOptions options) - { - _options = options.Value; - } - public IViewComponentResult Invoke(DocumentNotFoundPageModel model, string defaultErrorMessageKey) - { - model.DocumentsUrlPrefix = _options.RoutePrefix; - - return View("~/Pages/Documents/Shared/DocumentNotFoundComponent/Default.cshtml", model); - } - } -} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/Default.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml similarity index 62% rename from modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/Default.cshtml rename to modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml index 604ff05da7..c7c7db1006 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/DocumentNotFoundComponent/Default.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml @@ -1,16 +1,15 @@ -@using Volo.Docs.Pages.Documents.Shared.DocumentNotFoundComponent -@model DocumentNotFoundPageModel +@model Volo.Docs.Pages.Documents.Shared.ErrorComponent.ErrorPageModel @{ }
- 404 + @Model.ErrorCode

- "@Model.DocumentName" not found in @Model.ProjectName documents, with @Model.Version version and @Model.LanguageCode language. + @Model.ErrorMessage


- - Go Back + + Go Back (3)
diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorPageModel.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorPageModel.cs new file mode 100644 index 0000000000..cfb65409c7 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorPageModel.cs @@ -0,0 +1,11 @@ +namespace Volo.Docs.Pages.Documents.Shared.ErrorComponent +{ + public class ErrorPageModel + { + public string ErrorMessage { get; set; } + + public string ErrorCode { get; set; } + + public string RedirectUrl { get; set; } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorViewComponent.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorViewComponent.cs new file mode 100644 index 0000000000..493b6d896a --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/ErrorViewComponent.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.Docs.Pages.Documents.Shared.ErrorComponent +{ + public class ErrorViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke(ErrorPageModel model) + { + return View("~/Pages/Documents/Shared/ErrorComponent/Default.cshtml", model); + } + } +} From bb342a4b547396efbdece36774e41e4933af4f5a Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Sun, 19 Apr 2020 20:41:14 +0800 Subject: [PATCH 04/65] Update localization files --- .../Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json | 2 +- .../Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json index 761e28c1bb..8f3a3e44fb 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json @@ -14,7 +14,7 @@ "Projects": "项目", "NoProjectWarning": "还没有项目!", "DocumentNotFound": "找不到请求的文档!", - "ProjectNotFound": "找不到請求的項目!", + "ProjectNotFound": "找不到请求的项目!", "NavigationDocumentNotFound": "这个版本没有导航文件!", "DocumentNotFoundInSelectedLanguage": "本文档不适用于所选语言, 将以默认语言显示文档.", "FilterTopics": "过滤主题", diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json index 6a2f4d8799..dea171863c 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json @@ -14,6 +14,7 @@ "Projects": "專案", "NoProjectWarning": "沒有專案!", "DocumentNotFound": "找不到要求的文件!", + "ProjectNotFound": "找不到請求的項目!", "NavigationDocumentNotFound": "這個版本沒有導覽文件!", "DocumentNotFoundInSelectedLanguage": "本文件不適用於所選語系,將以預設語系顯示.", "FilterTopics": "過濾主題", From a3bd2f280e428195c65cff35dfcbc38df1780454 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Tue, 21 Apr 2020 16:20:19 +0800 Subject: [PATCH 05/65] Improve code --- .../Pages/Documents/Project/Index.cshtml | 2 +- .../Pages/Documents/Project/index.js | 73 +++++++------------ .../Shared/ErrorComponent/Default.cshtml | 8 +- .../Documents/Shared/ErrorComponent/error.js | 20 +++++ 4 files changed, 53 insertions(+), 50 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/error.js diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index fa1659ab54..f347ec2227 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -39,6 +39,7 @@ + } @if (Model.LoadSuccess) @@ -373,5 +374,4 @@ else } })) } - } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index d85b5a8630..71fb550539 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -203,31 +203,31 @@ 'YandexBot', 'msnbot', 'Rambler', - 'Yahoo', - 'AbachoBOT', - 'accoona', + 'Yahoo', + 'AbachoBOT', + 'accoona', 'AcoiRobot', 'ASPSeek', - 'CrocCrawler', + 'CrocCrawler', 'Dumbot', - 'FAST-WebCrawler', - 'GeonaBot', + 'FAST-WebCrawler', + 'GeonaBot', 'Gigabot', - 'Lycos', - 'MSRBOT', + 'Lycos', + 'MSRBOT', 'Scooter', 'AltaVista', - 'IDBot', - 'eStyle', - 'Scrubby', - 'Slurp', - 'DuckDuckBot', - 'Baiduspider', - 'VoilaBot', - 'ExaLead', - 'Search Dog', - 'MSN Bot' , - 'BingBot' + 'IDBot', + 'eStyle', + 'Scrubby', + 'Slurp', + 'DuckDuckBot', + 'Baiduspider', + 'VoilaBot', + 'ExaLead', + 'Search Dog', + 'MSN Bot', + 'BingBot' ]; var agent = navigator.userAgent; @@ -276,9 +276,8 @@ if (queryStrings.length <= 0) { returnList.push(key + "=" + $(this).val()); - - } - else { + + } else { for (var k = 0; k < queryStrings.length; k++) { returnList.push(key + "=" + $(this).val() + "&" + queryStrings[k]); } @@ -291,38 +290,22 @@ var queryStrings = getQueryStringsFromComboboxes(0); for (var i = 0; i < queryStrings.length; i++) { - html += "" + queryStrings[i]+" " + html += "" + queryStrings[i] + " " } $("#crawler_link").html(html); }; - - var errorPageRedirect = function(){ - var second = 3; - var close = setInterval(()=>{ - second--; - $(".seconds").text(`(${second})`) - if(second===0){ - clearInterval(close); - $(".redirect")[0].click(); - } - },1000) - } - var loadSuccess = $(".docs-page").length!==0; - if(loadSuccess === true){ - initNavigationFilter("sidebar-scroll"); + initNavigationFilter("sidebar-scroll"); + + initAnchorTags(".docs-page .docs-body"); - initAnchorTags(".docs-page .docs-body"); + initSocialShareLinks(); - initSocialShareLinks(); + initSections(); - initSections(); + initCrawlerLinks(); - initCrawlerLinks(); - }else{ - errorPageRedirect(); - } }); })(jQuery); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml index c7c7db1006..ff10a25f2a 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/Default.cshtml @@ -2,14 +2,14 @@ @{ }
-
- @Model.ErrorCode +
+ @Model.ErrorCode

@Model.ErrorMessage


- - Go Back (3) + + Go Back (3)
diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/error.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/error.js new file mode 100644 index 0000000000..d1d08829ac --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/ErrorComponent/error.js @@ -0,0 +1,20 @@ +(function ($) { + + $(function () { + var errorPageRedirect = function () { + var second = 3; + var close = setInterval(() => { + $("#ErrorRedirectSeconds").text(`(${--second})`); + if (second === 0) { + clearInterval(close); + $("#ErrorRedirect")[0].click(); + } + }, 1000); + } + + if (document.getElementById("DocumentErrorContainer")) { + errorPageRedirect(); + } + }); + +})(jQuery); From b89a54a3e7c549b07a198abe5406fab710d7d2b7 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 21 Apr 2020 11:52:03 +0300 Subject: [PATCH 06/65] docs: add Confirmation-Service.md --- docs/en/UI/Angular/Confirmation-Service.md | 168 +++++++++++++++++++++ docs/en/UI/Angular/images/confirmation.png | Bin 0 -> 26919 bytes 2 files changed, 168 insertions(+) create mode 100644 docs/en/UI/Angular/Confirmation-Service.md create mode 100644 docs/en/UI/Angular/images/confirmation.png diff --git a/docs/en/UI/Angular/Confirmation-Service.md b/docs/en/UI/Angular/Confirmation-Service.md new file mode 100644 index 0000000000..1164dd9de6 --- /dev/null +++ b/docs/en/UI/Angular/Confirmation-Service.md @@ -0,0 +1,168 @@ +# ConfirmationService + +You can use the `ConfirmationService` in @abp/ng.theme.shared package to place a confirmation popup at the root level. + + +## Getting Started + +You do not have to provide the `ConfirmationService` at module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components, directives, or services. + + +```js +import { ConfirmationService } from '@abp/ng.theme.shared'; + +@Component({ + /* class metadata here */ +}) +class DemoComponent { + constructor(private confirmation: ConfirmationService) {} +} +``` + +## Usage + +You can use the `success`, `warn`, `error`, and `info` methods of `ConfirmationService` to display a confirmation popup at the root level in your project. + +### How to Display a Confirmation Popup + +```js +const confirmationStatus$ = this.confirmation.success('Message', 'Title') +``` + +- The `ConfirmationService` methods accept three parameters that are `message`, `title`, and `options`. +- `success`, `warn`, `error`, and `info` methods return an [RxJS Subject](https://rxjs-dev.firebaseapp.com/guide/subject) to listen to confirmation popup closing event. The type of event value is [`Confirmation.Status`](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/theme-shared/src/lib/models/confirmation.ts#L24) that is an enum. + +### How to Listen Closing Event + +You can subscribe the confirmation closing event like below: + +```js +import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared'; + +constructor(private confirmation: ConfirmationService) {} + +this.confirmation + .warn('::WillBeDeleted', { key: '::AreYouSure', defaultValue: 'Are you sure?' }) + .subscribe((status: Confirmation.Status) => { + switch (status) { + case Confirmation.Status.confirm: + // confirmed, the popup was closed by clicking the confirm button + break; + case Confirmation.Status.reject: + // rejected, the popup was closed by clicking the cancel button + break; + case Confirmation.Status.dismiss: + // dismissed, the popup was closed by pressing the escape + break; + } + }); +``` + +- The `message` and `title` parameters accept a string, localization key or localization object. See the [localization document](./Localization.md) + +If the status is not important for you, you may not listen the closing event: + +```js +this.confirmation.error('You are not authorized.', 'Error'); +``` + +### How to Display a Confirmation Popup With Given Options + +Options can be passed as the third parameter to `success`, `warn`, `error`, and `info` methods: + +```js +const options: Partial = { + hideCancelBtn: false, + hideYesBtn: false, + cancelText: 'Close', + yesText: 'Confirm', + messageLocalizationParams: ['Demo'], + titleLocalizationParams: [], +}; + +this.confirmation.warn( + 'AbpIdentity::RoleDeletionConfirmationMessage', + 'Are you sure?', + options, +); +``` + +- `hideCancelBtn` option is the boolean value that allows the cancel button to be displayed or hidden. Default value is `false` +- `hideYesBtn` option is the boolean value that allows the confirm button to be displayed or hidden. Default value is `false` +- `cancelText` is the text of the cancel button. A localization key or localization object can be passed. Default value is `AbpUi::Cancel` +- `yesText` is the text of the confirm button. A localization key or localization object can be passed. Default value is `AbpUi::Yes` +- `messageLocalizationParams` is the interpolation parameters of the message localization. +- `titleLocalizationParams` is the interpolation parameters of the title localization. + +With the above options, the confirmation popup looks like this: + +![confirmation](./images/confirmation.png) + +### How to Remove a Confirmation Popup + +The open confirmation popup can be removed manually via the `clear` method: + +```js +this.confirmation.clear(); +``` + +## API + +### success + +```js +success( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): Observable +``` + +> See the [`Config.LocalizationParam` type](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/core/src/lib/models/config.ts#L46) and [`Confirmation` namespace](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/theme-shared/src/lib/models/confirmation.ts) + + +### warn + +```js +warn( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): Observable +``` + +### error + +```js +error( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): Observable +``` + +### info + +```js +info( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): Observable +``` + +### clear + +```js +clear( + status: Confirmation.Status = Confirmation.Status.dismiss +): void +``` + +- `status` parameter is the value of the confirmation closing event. + + +## What's Next? + +- ToasterService + \ No newline at end of file diff --git a/docs/en/UI/Angular/images/confirmation.png b/docs/en/UI/Angular/images/confirmation.png new file mode 100644 index 0000000000000000000000000000000000000000..efe4c98ea779b3798d21208966566711ec535629 GIT binary patch literal 26919 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 Date: Tue, 21 Apr 2020 13:35:42 +0300 Subject: [PATCH 07/65] docs: change a sentence in confirmation-service.md --- docs/en/UI/Angular/Confirmation-Service.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Confirmation-Service.md b/docs/en/UI/Angular/Confirmation-Service.md index 1164dd9de6..8722f88fd2 100644 --- a/docs/en/UI/Angular/Confirmation-Service.md +++ b/docs/en/UI/Angular/Confirmation-Service.md @@ -1,6 +1,6 @@ # ConfirmationService -You can use the `ConfirmationService` in @abp/ng.theme.shared package to place a confirmation popup at the root level. +You can use the `ConfirmationService` in @abp/ng.theme.shared package to display a confirmation popup by placing at the root level in your project. ## Getting Started @@ -21,7 +21,7 @@ class DemoComponent { ## Usage -You can use the `success`, `warn`, `error`, and `info` methods of `ConfirmationService` to display a confirmation popup at the root level in your project. +You can use the `success`, `warn`, `error`, and `info` methods of `ConfirmationService` to display a confirmation popup. ### How to Display a Confirmation Popup From 26b056c324341e65a8fc1c95e6de06542afe8878 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 22 Apr 2020 11:16:50 +0800 Subject: [PATCH 08/65] Improve code --- .../Pages/Documents/Project/Index.cshtml | 51 ++++++++++--------- .../Pages/Documents/Project/Index.cshtml.cs | 6 +-- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index f347ec2227..74f7c21464 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -153,11 +153,11 @@
-
@@ -172,11 +172,11 @@ - @@ -226,8 +226,8 @@ @if (!string.IsNullOrEmpty(Model.Document.EditLink)) { - - @(L["Edit"]) + + @(L["Edit"]) (@L["LastEditTime"]: @Model.Document.LastUpdatedTime.ToShortDateString()) } @@ -349,6 +349,19 @@ } else { + if (!Model.ProjectFound) + { + @(await Component.InvokeAsync(new + { + model = new ErrorPageModel + { + RedirectUrl = Model.DocumentsUrlPrefix, + ErrorCode = "404", + ErrorMessage = L.GetString("ProjectNotFound") + } + })) + } + if (!Model.DocumentFound) { @(await Component.InvokeAsync(new @@ -362,16 +375,4 @@ else } })) } - if (!Model.EntityFound) - { - @(await Component.InvokeAsync(new - { - model = new ErrorPageModel - { - RedirectUrl = Model.DocumentsUrlPrefix, - ErrorCode = "404", - ErrorMessage = L.GetString("ProjectNotFound") - } - })) - } -} \ No newline at end of file +} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index c57ee28fd3..f5758447e4 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -35,9 +35,9 @@ namespace Volo.Docs.Pages.Documents.Project public bool DocumentFound { get; set; } = true; - public bool EntityFound { get; set; } = true; + public bool ProjectFound { get; set; } = true; - public bool LoadSuccess => DocumentFound && EntityFound; + public bool LoadSuccess => DocumentFound && ProjectFound; public string DefaultLanguageCode { get; set; } @@ -122,7 +122,7 @@ namespace Volo.Docs.Pages.Documents.Project catch (EntityNotFoundException e) { Logger.LogWarning(e.Message); - EntityFound = false; + ProjectFound = false; return Page(); } From 07056aa9f3f075225bcb77e2ae7d1fa85e6d73c7 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 22 Apr 2020 15:37:32 +0800 Subject: [PATCH 09/65] Call SaveChanges after creating a new tenant. Resolve #3618 --- .../Volo/Abp/TenantManagement/TenantAppService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs index f618011cc7..575aa1eb0c 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs @@ -56,6 +56,8 @@ namespace Volo.Abp.TenantManagement await TenantRepository.InsertAsync(tenant); + await CurrentUnitOfWork.SaveChangesAsync(); + using (CurrentTenant.Change(tenant.Id, tenant.Name)) { //TODO: Handle database creation? From 177ffba81d18702e2ea870594e89c6ca0075b9be Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Wed, 22 Apr 2020 13:04:43 +0300 Subject: [PATCH 10/65] docs: add description for Confirmation.Status enum resolves #3606 --- docs/en/UI/Angular/Confirmation-Service.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/en/UI/Angular/Confirmation-Service.md b/docs/en/UI/Angular/Confirmation-Service.md index 8722f88fd2..56e8f1ce35 100644 --- a/docs/en/UI/Angular/Confirmation-Service.md +++ b/docs/en/UI/Angular/Confirmation-Service.md @@ -44,21 +44,17 @@ constructor(private confirmation: ConfirmationService) {} this.confirmation .warn('::WillBeDeleted', { key: '::AreYouSure', defaultValue: 'Are you sure?' }) .subscribe((status: Confirmation.Status) => { - switch (status) { - case Confirmation.Status.confirm: - // confirmed, the popup was closed by clicking the confirm button - break; - case Confirmation.Status.reject: - // rejected, the popup was closed by clicking the cancel button - break; - case Confirmation.Status.dismiss: - // dismissed, the popup was closed by pressing the escape - break; - } + // your code here }); ``` + - The `message` and `title` parameters accept a string, localization key or localization object. See the [localization document](./Localization.md) +- `Confirmation.Status` is an enum and has three properties; + - `Confirmation.Status.confirm` is a closing event value that will be emitted when the popup is closed by the confirm button. + - `Confirmation.Status.reject` is a closing event value that will be emitted when the popup is closed by the cancel button. + - `Confirmation.Status.dismiss` is a closing event value that will be emitted when the popup is closed by pressing the escape. + If the status is not important for you, you may not listen the closing event: From 7b8fd341c4004588fa7bd3725fed95f0130d1be4 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 22 Apr 2020 20:14:29 +0800 Subject: [PATCH 11/65] Update document --- docs/zh-Hans/API/Auto-API-Controllers.md | 4 +-- docs/zh-Hans/Application-Services.md | 2 +- .../zh-Hans/AspNetCore/Tag-Helpers/Buttons.md | 2 +- docs/zh-Hans/Audit-Logging.md | 32 +++++++++---------- docs/zh-Hans/Authorization.md | 2 +- docs/zh-Hans/Background-Workers.md | 4 +-- docs/zh-Hans/Blog-Posts/2019-02-22/Post.md | 14 ++++---- .../2019-06-19 v0_18_Release/Post.md | 12 +++---- .../2019-08-16 v0_19_Release/Post.md | 4 +-- .../2019-09-25 v0_21_Release/Post.md | 4 +-- .../2020-03-19 v2_3_Release/Post.md | 16 +++++----- docs/zh-Hans/CLI.md | 14 ++++---- ...Application-Modules-Overriding-Services.md | 2 +- docs/zh-Hans/Entities.md | 6 ++-- .../Entity-Framework-Core-Migrations.md | 14 ++++---- docs/zh-Hans/Entity-Framework-Core-MySQL.md | 6 ++-- .../Entity-Framework-Core-Other-DBMS.md | 2 +- .../Entity-Framework-Core-PostgreSQL.md | 4 +-- docs/zh-Hans/Entity-Framework-Core-SQLite.md | 4 +-- docs/zh-Hans/Entity-Framework-Core.md | 10 +++--- .../Getting-Started-AspNetCore-Application.md | 2 +- ...Getting-Started-AspNetCore-MVC-Template.md | 2 +- docs/zh-Hans/Index.md | 2 +- docs/zh-Hans/Modules/Docs.md | 12 +++---- docs/zh-Hans/Object-Extensions.md | 8 ++--- docs/zh-Hans/Object-To-Object-Mapping.md | 4 +-- docs/zh-Hans/Options.md | 10 +++--- docs/zh-Hans/Samples/Microservice-Demo.md | 24 +++++++------- docs/zh-Hans/Settings.md | 2 +- docs/zh-Hans/Startup-Templates/Application.md | 4 +-- docs/zh-Hans/Startup-Templates/Index.md | 2 +- .../Tutorials/AspNetCore-Mvc/Part-I.md | 8 ++--- .../Tutorials/AspNetCore-Mvc/Part-III.md | 4 +-- .../UI/Angular/Component-Replacement.md | 2 +- docs/zh-Hans/UI/Angular/Config-State.md | 8 ++--- docs/zh-Hans/UI/Angular/Content-Strategy.md | 2 +- docs/zh-Hans/UI/Angular/Context-Strategy.md | 2 +- .../UI/Angular/Dom-Insertion-Service.md | 10 ++++++ docs/zh-Hans/UI/Angular/Lazy-Load-Service.md | 2 +- .../UI/Angular/Permission-Management.md | 2 +- .../UI/AspNetCore/Bundling-Minification.md | 2 +- .../AspNetCore/Tag-Helpers/Progress-Bars.md | 2 +- docs/zh-Hans/Validation.md | 4 +-- docs/zh-Hans/Virtual-File-System.md | 2 +- 44 files changed, 145 insertions(+), 135 deletions(-) diff --git a/docs/zh-Hans/API/Auto-API-Controllers.md b/docs/zh-Hans/API/Auto-API-Controllers.md index 93ac124913..c3f5d44d71 100644 --- a/docs/zh-Hans/API/Auto-API-Controllers.md +++ b/docs/zh-Hans/API/Auto-API-Controllers.md @@ -6,7 +6,7 @@ ABP可以按照惯例 **自动** 将你的应用程序服务配置为API控制 ## 配置 -基本配置很简单. 只需配置`AbpAspNetCoreMvcOptions`并使用`ConventionalControllers.Create`方法,如下所示: +基本配置很简单. 只需配置`AbpAspNetCoreMvcOptions`并使用`ConventionalControllers.Create`方法,如下所示: ````csharp [DependsOn(BookStoreApplicationModule)] @@ -82,7 +82,7 @@ Configure(options => * 删除'**Async**'后缀. 如果方法名称为'GetPhonesAsync',则变为`GetPhones`. * 删除**HTTP method前缀**. 基于的HTTP method删除`GetList`,`GetAll`,`Get`,`Put`,`Update`,`Delete`,`Remove`,`Create`,`Add`,`Insert`,`Post`和`Patch`前缀, 因此`GetPhones`变为`Phones`, 因为`Get`前缀和GET请求重复. * 将结果转换为**camelCase**. - * 如果生成的操作名称为**空**,则它不会添加到路径中.否则它会被添加到路由中(例如'/phones').对于`GetAllAsync`方法名称,它将为空,因为`GetPhonesAsync`方法名称将为`phone`. + * 如果生成的操作名称为**空**,则它不会添加到路径中.否则它会被添加到路由中(例如'/phones').对于`GetAllAsync`方法名称,它将为空,因为`GetPhonesAsync`方法名称将为`phone`. * 可以通过设置`UrlActionNameNormalizer`选项来自定义.It's an action delegate that is called for every method. * 如果有另一个带有'Id'后缀的参数,那么它也会作为最终路线段添加到路线中(例如'/phoneId'). diff --git a/docs/zh-Hans/Application-Services.md b/docs/zh-Hans/Application-Services.md index 72e0319cde..d0e29c2881 100644 --- a/docs/zh-Hans/Application-Services.md +++ b/docs/zh-Hans/Application-Services.md @@ -380,4 +380,4 @@ public class DistrictKey ### 生命周期 -应用服务的生命周期是[transient](Dependency-Injection)的,它们会自动注册到依赖注入系统. \ No newline at end of file +应用服务的生命周期是[transient](Dependency-Injection)的,它们会自动注册到依赖注入系统. \ No newline at end of file diff --git a/docs/zh-Hans/AspNetCore/Tag-Helpers/Buttons.md b/docs/zh-Hans/AspNetCore/Tag-Helpers/Buttons.md index 848d043312..ebfeb6f2aa 100644 --- a/docs/zh-Hans/AspNetCore/Tag-Helpers/Buttons.md +++ b/docs/zh-Hans/AspNetCore/Tag-Helpers/Buttons.md @@ -86,7 +86,7 @@ ABP框架定义了Tag Helper用于简单的创建bootstrap按钮. ### `icon-type` -`icon-type` 是一个可选参数。它的默认值是 `FontAwesome`. 你可以创建自己的图标类型提供程序并更改它. +`icon-type` 是一个可选参数.它的默认值是 `FontAwesome`. 你可以创建自己的图标类型提供程序并更改它. 你可以为按钮选择以下图标类型: diff --git a/docs/zh-Hans/Audit-Logging.md b/docs/zh-Hans/Audit-Logging.md index a028e640b2..a8b6e66449 100644 --- a/docs/zh-Hans/Audit-Logging.md +++ b/docs/zh-Hans/Audit-Logging.md @@ -43,12 +43,12 @@ Configure(options => * `IsEnabledForGetRequests` (默认值: `false`): HTTP GET请求通常不应该在数据库进行任何更改,审计日志系统不会为GET请求保存审计日志对象. 将此值设置为 `true` 可为GET请求启用审计日志系统. * `ApplicationName`: 如果有多个应用程序保存审计日志到单一的数据库,使用此属性设置为你的应用程序名称区分不同的应用程序日志. * `IgnoredTypes`: 审计日志系统忽略的 `Type` 列表. 如果它是实体类型,则不会保存此类型实体的更改. 在序列化操作参数时也使用此列表. -* `EntityHistorySelectors`:选择器列表,用于确定是否选择了用于保存实体更改的实体类型. 有关详细信息请参阅下面的部分. +* `EntityHistorySelectors`:选择器列表,用于确定是否选择了用于保存实体更改的实体类型. 有关详细信息请参阅下面的部分. * `Contributors`: `AuditLogContributor` 实现的列表. 贡献者是扩展审计日志系统的一种方式. 有关详细信息请参阅下面的"审计日志贡献者"部分. ### 实体历史选择器 -保存您的所有实体的所有变化将需要大量的数据库空间. 出于这个原因**审计日志系统不保存为实体的任何改变,除非你明确地对其进行配置**. +保存你的所有实体的所有变化将需要大量的数据库空间. 出于这个原因**审计日志系统不保存为实体的任何改变,除非你明确地对其进行配置**. 要保存的所有实体的所有更改,只需使用 `AddAllEntities()` 扩展方法. @@ -131,7 +131,7 @@ public class HomeController : AbpController 可以为任何类型的类(注册到[依赖注入](Dependency-Injection.md)并从依赖注入解析)启用审计日志,默认情况下仅对控制器和应用程序服务启用. -对于任何需要被审计记录的类或方法都可以使用 `[Audited]` 和`IAuditingEnabled`.此外,您的类可以(直接或固有的)实现 `IAuditingEnabled` 接口以认启用该类的审计日志记录. +对于任何需要被审计记录的类或方法都可以使用 `[Audited]` 和`IAuditingEnabled`.此外,你的类可以(直接或固有的)实现 `IAuditingEnabled` 接口以认启用该类的审计日志记录. ### 启用/禁用 实体 & 属性 @@ -211,8 +211,8 @@ public class MyUser : Entity * **AuditLogInfo**: 具有以下属性: * `ApplicationName`: 当你保存不同的应用审计日志到同一个数据库,这个属性用来区分应用程序. - * `UserId`:当前用户的Id,用户未登录为 `null`. - * `UserName`:当前用户的用户名,如果用户已经登录(这里的值不依赖于标识模块/系统进行查找). + * `UserId`:当前用户的Id,用户未登录为 `null`. + * `UserName`:当前用户的用户名,如果用户已经登录(这里的值不依赖于标识模块/系统进行查找). * `TenantId`: 当前租户的Id,对于多租户应用. * `TenantName`: 当前租户的名称,对于多租户应用. * `ExecutionTime`: 审计日志对象创建的时间. @@ -222,28 +222,28 @@ public class MyUser : Entity * `ClientIpAddress`: 客户端/用户设备的IP地址. * `CorrelationId`: 当前[相关Id](CorrelationId.md). 相关Id用于在单个逻辑操作中关联由不同应用程序(或微服务)写入的审计日志. * `BrowserInfo`: 当前用户的浏览器名称/版本信息,如果有的话. - * `HttpMethod`: 当前HTTP请求的方法(GET,POST,PUT,DELETE ...等). + * `HttpMethod`: 当前HTTP请求的方法(GET,POST,PUT,DELETE ...等). * `HttpStatusCode`: HTTP响应状态码. * `Url`: 请求的URL. * **AuditLogActionInfo**: 一个 审计日志动作通常是web请求期间控制器动作或[应用服务](Application-Services.md)方法调用. 一个审计日志可以包含多个动作. 动作对象具有以下属性: - * `ServiceName`:执行的控制器/服务的名称. - * `MethodName`:控制器/服务执行的方法的名称. - * `Parameters`:传递给方法的参数的JSON格文本. + * `ServiceName`:执行的控制器/服务的名称. + * `MethodName`:控制器/服务执行的方法的名称. + * `Parameters`:传递给方法的参数的JSON格文本. * `ExecutionTime`: 执行的时间. * `ExecutionDuration`: 方法执行时长,以毫秒为单位. 可以用来观察方法的性能. * **EntityChangeInfo**: 表示一个实体在Web请求中的变更. 审计日志可以包含0个或多个实体的变更. 实体变更具有以下属性: * `ChangeTime`: 当实体被改变的时间. - * `ChangeType`:具有以下字段的枚举: `Created`(0), `Updated`(1)和 `Deleted`(2). + * `ChangeType`:具有以下字段的枚举: `Created`(0), `Updated`(1)和 `Deleted`(2). * `EntityId`: 更改实体的Id. - * `EntityTenantId`:实体所属的租户Id. + * `EntityTenantId`:实体所属的租户Id. * `EntityTypeFullName`: 实体的类型(类)的完整命名空间名称(例如Book实体的*Acme.BookStore.Book*. * **EntityPropertyChangeInfo**: 表示一个实体的属性的更改.一个实体的更改信息(上面已说明)可含有具有以下属性的一个或多个属性的更改: * `NewValue`: 属性的新值. 如果实体已被删除为 `null`. - * `OriginalValue`:变更前旧/初始值. 如果实体是新创建为 `null`. + * `OriginalValue`:变更前旧/初始值. 如果实体是新创建为 `null`. * `PropertyName`: 实体类的属性名称. - * `PropertyTypeFullName`:属性类型的完整命名空间名称. + * `PropertyTypeFullName`:属性类型的完整命名空间名称. * **Exception**: 审计日志对象可能包含零个或多个异常. 可以得到失败请求的异常信息. -* **Comment**:用于将自定义消息添加到审计日志条目的任意字符串值. 审计日志对象可能包含零个或多个注释. +* **Comment**:用于将自定义消息添加到审计日志条目的任意字符串值. 审计日志对象可能包含零个或多个注释. 除了上面说明的标准属性之外,`AuditLogInfo`, `AuditLogActionInfo` 和 `EntityChangeInfo` 对象还实现了`IHasExtraProperties` 接口,你可以向这些对象添加自定义属性. @@ -331,7 +331,7 @@ public class MyService : ITransientDependency ### 手动创建审计日志范围 你很少需要手动创建审计日志的范围,但如果你需要,可以使用 `IAuditingManager` 创建审计日志的范围. -例: +例: ````csharp public class MyService : ITransientDependency @@ -366,7 +366,7 @@ public class MyService : ITransientDependency } ```` -您可以调用其他服务,它们可能调用其他服务,它们可能更改实体,等等. 所有这些交互都保存为finally块中的一个审计日志对象. +你可以调用其他服务,它们可能调用其他服务,它们可能更改实体,等等. 所有这些交互都保存为finally块中的一个审计日志对象. ## 审计日志模块 diff --git a/docs/zh-Hans/Authorization.md b/docs/zh-Hans/Authorization.md index a43565279e..99139be3ac 100644 --- a/docs/zh-Hans/Authorization.md +++ b/docs/zh-Hans/Authorization.md @@ -153,7 +153,7 @@ myGroup.AddPermission( myGroup.AddPermission("Author_Management", isEnabled: false); ```` -通常你不需要定义禁用权限(除非您暂时想要禁用应用程序的功能). 无论怎样,你可能想要禁用依赖模块中定义的权限,这样你可以禁用相关的功能. 参阅下面的 "*更改依赖模块的权限定义*" 节,查看示例用法. +通常你不需要定义禁用权限(除非你暂时想要禁用应用程序的功能). 无论怎样,你可能想要禁用依赖模块中定义的权限,这样你可以禁用相关的功能. 参阅下面的 "*更改依赖模块的权限定义*" 节,查看示例用法. > 注意:检查一个未定义的权限会抛出异常,而被禁用的权限的返回禁止(false). diff --git a/docs/zh-Hans/Background-Workers.md b/docs/zh-Hans/Background-Workers.md index dfd26c7b82..1daedde384 100644 --- a/docs/zh-Hans/Background-Workers.md +++ b/docs/zh-Hans/Background-Workers.md @@ -2,7 +2,7 @@ ## 介绍 -背景工人在应用简单独立的线程在后台运行。一般来说,他们定期运行,以执行一些任务。例子; +背景工人在应用简单独立的线程在后台运行.一般来说,他们定期运行,以执行一些任务.例子; 后台工作者在应用程序后台运行的简单的独立线程,一般来说它们定期运行执行一些任务.例如; * 后台工作者可以定期**删除过时的日志**. @@ -72,7 +72,7 @@ public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase } ```` -* `AsyncPeriodicBackgroundWorkerBase` 使用 `AbpTimer`(线程安全定时器)对象来确定**时间段**. 我们可以在构造函数中设置了`Period` 属性。 +* `AsyncPeriodicBackgroundWorkerBase` 使用 `AbpTimer`(线程安全定时器)对象来确定**时间段**. 我们可以在构造函数中设置了`Period` 属性. * 它需要实现 `DoWorkAsync` 方法**执行**定期任务. * 最好使用 `PeriodicBackgroundWorkerContext` **解析依赖** 而不是构造函数. 因为 `AsyncPeriodicBackgroundWorkerBase` 使用 `IServiceScope` 在你的任务执行结束时会对其 **disposed**. * `AsyncPeriodicBackgroundWorkerBase` **捕获并记录** 由 `DoWorkAsync` 方法抛出的 **异常**. diff --git a/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md b/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md index 30a5d691e9..998a454abc 100644 --- a/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md +++ b/docs/zh-Hans/Blog-Posts/2019-02-22/Post.md @@ -13,7 +13,7 @@ ABP框架的主要目标之一是提供[创建微服务解决方案的便利基 - 使用[Ocelot](https://github.com/ThreeMammals/Ocelot)库开发了多个**网关** / BFF(后端为前端(Backend for Frontends)). - 使用[IdentityServer](https://identityserver.io/)框架开发**身份验证服务**.它也是一个带有必要UI的SSO(单点登录)应用程序. - 有**多个数据库**.一些微服务有自己的数据库,而一些服务/应用程序共享一个数据库(以演示不同的用例). -- 具有不同类型的数据库:**SQL Server**(使用**Entity Framework Core** ORM)和**MongoDB**. +- 具有不同类型的数据库:**SQL Server**(使用**Entity Framework Core** ORM)和**MongoDB**. - 有一个**控制台应用程序**来显示通过身份验证使用服务的最简单方法. - 使用[Redis](https://redis.io/)进行**分布式缓存**. - 使用[RabbitMQ](https://www.rabbitmq.com/)进行服务到服务(service-to-service)的**消息传递**. @@ -28,27 +28,27 @@ ABP框架的主要目标之一是提供[创建微服务解决方案的便利基 ## 路线图 -在第一个稳定版本(v1.0)之前还有很多工作要做.您可以在GitHub仓库上看到[优先的积压项目](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3ABacklog). +在第一个稳定版本(v1.0)之前还有很多工作要做.你可以在GitHub仓库上看到[优先的积压项目](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3ABacklog). 根据我们的估计,我们计划在2019年第二季度(可能在五月或六月)发布v1.0.所以,不用等待太长时间了.我们也对第一个稳定版本感到非常兴奋. 我们还将完善[文档](https://abp.io/documents/abp/latest),因为它现在还远未完成. -第一个版本可能不包含SPA模板.但是,如果可能的话,我们想要准备一个简单些的.SPA框架还没有确定下来.备选有:**Angular,React和Blazor**.请将您的想法写为对此帖的评论. +第一个版本可能不包含SPA模板.但是,如果可能的话,我们想要准备一个简单些的.SPA框架还没有确定下来.备选有:**Angular,React和Blazor**.请将你的想法写为对此帖的评论. ## 中文网 -中国有一个大型的ABP社区.他们创建了一个中文版的abp.io网站:https://abp.io/. 他们一直在保持更新.感谢中国的开发人员,特别是[Liming Ma](https://github.com/maliming). +中国有一个大型的ABP社区.他们创建了一个中文版的abp.io网站:https://abp.io/. 他们一直在保持更新.感谢中国的开发人员,特别是[Liming Ma](https://github.com/maliming). ## NDC {London} 2019 很高兴作为合作伙伴参加[NDC {London}](https://ndc-london.com/)2019 .我们已经与许多开发人员讨论过当前的ASP.NET Boilerplate和ABP vNext,我们得到了很好的反馈. -我们还有机会与[Scott Hanselman](https://twitter.com/shanselman)和[Jon Galloway](https://twitter.com/jongalloway)交谈.他们参观了我们的展位,我们谈到了ABP vNext的想法.他们喜欢新的ABP框架的功能,方法和目标.在twitter上查看一些照片和评论: +我们还有机会与[Scott Hanselman](https://twitter.com/shanselman)和[Jon Galloway](https://twitter.com/jongalloway)交谈.他们参观了我们的展位,我们谈到了ABP vNext的想法.他们喜欢新的ABP框架的功能,方法和目标.在twitter上查看一些照片和评论: ![scott-and-jon](scott-and-jon.png) ## 跟上步伐 -* 您可以标星并关注**GitHub**存储库:https://github.com/abpframework/abp -* 您可以关注官方**Twitter**帐户获取新闻:https://twitter.com/abpframework +* 你可以标星并关注**GitHub**存储库:https://github.com/abpframework/abp +* 你可以关注官方**Twitter**帐户获取新闻:https://twitter.com/abpframework diff --git a/docs/zh-Hans/Blog-Posts/2019-06-19 v0_18_Release/Post.md b/docs/zh-Hans/Blog-Posts/2019-06-19 v0_18_Release/Post.md index a25e1c0a97..6b3c76d2e2 100644 --- a/docs/zh-Hans/Blog-Posts/2019-06-19 v0_18_Release/Post.md +++ b/docs/zh-Hans/Blog-Posts/2019-06-19 v0_18_Release/Post.md @@ -4,7 +4,7 @@ ABP v0.18已发布, 包含解决的[80+个issue](https://github.com/abpframework ## 网站更改 -[abp.io](https://abp.io)网站**完全更新**以突出ABP框架的目标和重要功能.文档和博客网址也会更改: +[abp.io](https://abp.io)网站**完全更新**以突出ABP框架的目标和重要功能.文档和博客网址也会更改: - `abp.io/documents`移至[docs.abp.io](https://docs.abp.io). - `abp.io/blog`转移到[blog.abp.io](https://blog.abp.io). @@ -21,25 +21,25 @@ ABP CLI现在是创建新项目的首选方式,你仍然可以从[开始](https: ### 用法 -使用命令行窗口安装ABP CLI: +使用命令行窗口安装ABP CLI: ```` bash dotnet tool install -g Volo.Abp.Cli ```` -创建一个新应用程序: +创建一个新应用程序: ```` bash abp new Acme.BookStore ```` -将模块添加到应用程序: +将模块添加到应用程序: ```` bash abp add-module Volo.Blogging ```` -更新解决方案中所有与ABP相关的包: +更新解决方案中所有与ABP相关的包: ```` bash abp update @@ -59,7 +59,7 @@ abp update ## 更改日志 -以下是此版本附带的一些其他功能和增强功能: +以下是此版本附带的一些其他功能和增强功能: * 新[Volo.Abp.Dapper](https://www.nuget.org/packages/Volo.Abp.Dapper)包. * 新[Volo.Abp.Specifications](https://www.nuget.org/packages/Volo.Abp.Specifications)包. diff --git a/docs/zh-Hans/Blog-Posts/2019-08-16 v0_19_Release/Post.md b/docs/zh-Hans/Blog-Posts/2019-08-16 v0_19_Release/Post.md index 831cc791e9..9f82f6dce3 100644 --- a/docs/zh-Hans/Blog-Posts/2019-08-16 v0_19_Release/Post.md +++ b/docs/zh-Hans/Blog-Posts/2019-08-16 v0_19_Release/Post.md @@ -14,12 +14,12 @@ ABP v0.19已发布,包含解决的[~90个问题](https://github.com/abpframework * 更新了[ABP CLI](https://docs.abp.io/en/abp/latest/CLI)和[下载页面](https://abp.io/get-started),以便能够使用新的UI选项生成项目. * 创建了[教程](https://docs.abp.io/en/abp/latest/Tutorials/Angular/Part-I)以使用新的UI选项快速入门. -我们基于最新的Angular工具和趋势创建了模板,文档和基础架构: +我们基于最新的Angular工具和趋势创建了模板,文档和基础架构: * 使用[NgBootstrap](https://ng-bootstrap.github.io/)和[PrimeNG](https://www.primefaces.org/primeng/)作为UI组件库.你可以使用自己喜欢的库,没问题,但预构建的模块可以使用这些库. * 使用[NGXS](https://ngxs.gitbook.io/ngxs/)作为状态管理库. -Angular是第一个SPA UI选项,但它不是最后一个.在v1.0发布之后,我们将开始第二个UI选项的工作.虽然尚未决定,但候选的有Blazor,React和Vue.js. 等待你的反馈.你可以使用以下issue进行投票(thumb): +Angular是第一个SPA UI选项,但它不是最后一个.在v1.0发布之后,我们将开始第二个UI选项的工作.虽然尚未决定,但候选的有Blazor,React和Vue.js. 等待你的反馈.你可以使用以下issue进行投票(thumb): * [Blazor](https://github.com/abpframework/abp/issues/394) * [Vue.js](https://github.com/abpframework/abp/issues/1168) diff --git a/docs/zh-Hans/Blog-Posts/2019-09-25 v0_21_Release/Post.md b/docs/zh-Hans/Blog-Posts/2019-09-25 v0_21_Release/Post.md index 7633f3ea33..c4d98244fb 100644 --- a/docs/zh-Hans/Blog-Posts/2019-09-25 v0_21_Release/Post.md +++ b/docs/zh-Hans/Blog-Posts/2019-09-25 v0_21_Release/Post.md @@ -14,8 +14,8 @@ ABP框架越来越接近v1.0.我们打算在今年10月中旬发布1.0. 现在, ## Techorama荷兰2019 -[Techorama NL](https://techorama.nl/)是欧洲最大的会议之一.今年,Volosoft是会议的赞助商,并将有一个展位与软件开发人员讨论ABP框架和软件开发.我们的展位墙如下图所示: +[Techorama NL](https://techorama.nl/)是欧洲最大的会议之一.今年,Volosoft是会议的赞助商,并将有一个展位与软件开发人员讨论ABP框架和软件开发.我们的展位墙如下图所示: ![volosoft-booth](volosoft-booth.png) -如果您也参加会议,请到展位讨论ABP框架.我们还为您准备了一些私货:) +如果你也参加会议,请到展位讨论ABP框架.我们还为你准备了一些私货:) diff --git a/docs/zh-Hans/Blog-Posts/2020-03-19 v2_3_Release/Post.md b/docs/zh-Hans/Blog-Posts/2020-03-19 v2_3_Release/Post.md index a17bef2e1b..73585582f5 100644 --- a/docs/zh-Hans/Blog-Posts/2020-03-19 v2_3_Release/Post.md +++ b/docs/zh-Hans/Blog-Posts/2020-03-19 v2_3_Release/Post.md @@ -24,7 +24,7 @@ 我们终于完成了**react native移动应用程序**.目前,它可以让你**登录**,管理**用户**和**租户**.它利用ABP框架相同的设置,授权和本地化系统. -应用程序的一些截图: +应用程序的一些截图: ![mobile-ui](react-native-ui.png) @@ -34,7 +34,7 @@ 从我们的Angular应用程序中调用服务器中的REST端点是很常见的.这种情况下,我们一般创建**服务**(在服务器上包含各个服务的方法)和**模型对象**(对应服务器上的[DTO](https://docs.abp.io/en/abp/latest/Data-Transfer-Objects)). -除了手动创建这样的与服务器交互的服务外,我们可以使用像[NSWAG](https://github.com/RicoSuter/NSwag)工具来为我们生成服务代理.但是NSWAG有以下几个我们遇到的问题: +除了手动创建这样的与服务器交互的服务外,我们可以使用像[NSWAG](https://github.com/RicoSuter/NSwag)工具来为我们生成服务代理.但是NSWAG有以下几个我们遇到的问题: * 它产生一个**大,单一**的.ts文件; * 当你的应用程序增长时,它变得**太大**了. @@ -58,12 +58,12 @@ abp generate-proxy ### 添加模块的源代码 -应用程序启动模板带有一些[应用模块](https://docs.abp.io/en/abp/latest/Modules/Index), 以**Nuget和NPM包**的方式**预先安装了** .这样做有几个重要的优点: +应用程序启动模板带有一些[应用模块](https://docs.abp.io/en/abp/latest/Modules/Index), 以**Nuget和NPM包**的方式**预先安装了** .这样做有几个重要的优点: * 当新版本可用时, 你可以 **轻松地[升级](https://docs.abp.io/en/abp/latest/CLI#update)** 这些模块. * 你的解决方案**更干净**,这样你就可以专注于自己的代码. -但是,当你需要对一个依赖的模块**大量定制**时,就不如它的代码在你的应用程序中那么容易.为了解决这个问题,我们引入了一个[ABP CLI](https://docs.abp.io/en/abp/latest/CLI)的新命令, 在你的解决方案中用代码**替换**Nuget包.用法很简单: +但是,当你需要对一个依赖的模块**大量定制**时,就不如它的代码在你的应用程序中那么容易.为了解决这个问题,我们引入了一个[ABP CLI](https://docs.abp.io/en/abp/latest/CLI)的新命令, 在你的解决方案中用代码**替换**Nuget包.用法很简单: ````bash abp add-module --with-source-code @@ -75,19 +75,19 @@ abp add-module --with-source-code 此外,我们也创建了文档来说明如何定制依赖的模块而不改变它们的源代码(见下面的部分).仍然建议以包的方式使用模块,以便在以后可以轻松升级. -> 免费模块的源代码是**MIT**许可,所以你可以自由更改它们并添加到您的解决方案中. +> 免费模块的源代码是**MIT**许可,所以你可以自由更改它们并添加到你的解决方案中. ### 切换到预览版 ABP框架正在迅速发展,我们经常发布新版本.不过,如果你想更紧密地追随它,你可以使用**每日预览包**. -我们创建了一个ABP CLI命令来轻松地为你的解决方案**更新到最新的预览包**.在你的解决方案的根文件夹中运行以下命令: +我们创建了一个ABP CLI命令来轻松地为你的解决方案**更新到最新的预览包**.在你的解决方案的根文件夹中运行以下命令: ````bash abp switch-to-preview ```` -它会修改所有ABP相关的NuGet和NPM包的版本.当你需要时你也可以**切换回最新稳定版**: +它会修改所有ABP相关的NuGet和NPM包的版本.当你需要时你也可以**切换回最新稳定版**: ````bash abp switch-to-stable @@ -131,7 +131,7 @@ abp switch-to-stable ## 下一步? -我们未来几个月的目标如下: +我们未来几个月的目标如下: * 完成**文档和示例**,写更多的教程. * 使框架和现有模块的更加**可定制和可扩展**. diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md index 0a802ffdc1..4d037ef2fd 100644 --- a/docs/zh-Hans/CLI.md +++ b/docs/zh-Hans/CLI.md @@ -41,12 +41,12 @@ abp new Acme.BookStore * `--template` 或者 `-t`: 指定模板. 默认的模板是 `app`,会生成web项目.可用的模板有: * `app` (default): [应用程序模板](Startup-Templates/Application.md). 其他选项: - * `--ui` 或者 `-u`: 指定ui框架.默认`mvc`框架.其他选项: - * `mvc`: ASP.NET Core MVC.此模板的其他选项: + * `--ui` 或者 `-u`: 指定ui框架.默认`mvc`框架.其他选项: + * `mvc`: ASP.NET Core MVC.此模板的其他选项: * `--tiered`: 创建分层解决方案,Web和Http Api层在物理上是分开的.如果未指定会创建一个分层的解决方案,此解决方案没有那么复杂,适合大多数场景. - * `angular`: Angular. 这个模板还有一些额外的选项: + * `angular`: Angular. 这个模板还有一些额外的选项: * `--separate-identity-server`: 将Identity Server应用程序与API host应用程序分开. 如果未指定,则服务器端将只有一个端点. - * `none`: 无UI. 这个模板还有一些额外的选项: + * `none`: 无UI. 这个模板还有一些额外的选项: * `--separate-identity-server`: 将Identity Server应用程序与API host应用程序分开. 如果未指定,则服务器端将只有一个端点. * `--mobile` 或者 `-m`: 指定移动应用程序框架. 默认框架是 `react-native`. 其他选项: * `none`: 不包含移动应用程序. @@ -57,7 +57,7 @@ abp new Acme.BookStore * `module`: [Module template](Startup-Templates/Module.md). 其他选项: * `--no-ui`: 不包含UI.仅创建服务模块(也称为微服务 - 没有UI). * `--output-folder` 或者 `-o`: 指定输出文件夹,默认是当前目录. -* `--version` 或者 `-v`: 指定ABP和模板的版本.它可以是 [release tag](https://github.com/abpframework/abp/releases) 或者 [branch name](https://github.com/abpframework/abp/branches). 如果没有指定,则使用最新版本.大多数情况下,您会希望使用最新的版本. +* `--version` 或者 `-v`: 指定ABP和模板的版本.它可以是 [release tag](https://github.com/abpframework/abp/releases) 或者 [branch name](https://github.com/abpframework/abp/branches). 如果没有指定,则使用最新版本.大多数情况下,你会希望使用最新的版本. * `--template-source` 或者 `-ts`: 指定自定义模板源用于生成项目,可以使用本地源和网络源(例如 `D\localTemplate` 或 `https://.zip`). * `--create-solution-folder` 或者 `-csf`: 指定项目是在输出文件夹中的新文件夹中还是直接在输出文件夹中. * `--connection-string` 或者 `-cs`: 重写所有 `appsettings.json` 文件的默认连接字符串. 默认连接字符串是 `Server=localhost;Database=MyProjectName;Trusted_Connection=True;MultipleActiveResultSets=true`. 如果你不想使用默认,你可以设置自己的连接字符串. 默认的数据库提供程序是 `SQL Server`, 所以你只能输入SQL Server连接字符串! @@ -186,9 +186,9 @@ abp generate-proxy [options] #### Options -* `--apiUrl` 或者 `-a`:指定HTTP API的根URL. 如果未指定这个选项,默认使用你Angular应用程序的`environment.ts`文件API URL. 在运行 `generate-proxy` 命令之前,你的host必须启动正在运行. +* `--apiUrl` 或者 `-a`:指定HTTP API的根URL. 如果未指定这个选项,默认使用你Angular应用程序的`environment.ts`文件API URL. 在运行 `generate-proxy` 命令之前,你的host必须启动正在运行. * `--ui` 或者 `-u`: 指定UI框架,默认框架是angular.当前只有angular一个选项, 但我们会通过更改CLI增加新的选项. 尽请关注! -* `--module` 或者 `-m`:指定模块名. 默认模块名称为app. 如果你想所有模块,你可以指定 `--module all` 命令. +* `--module` 或者 `-m`:指定模块名. 默认模块名称为app. 如果你想所有模块,你可以指定 `--module all` 命令. 示例: diff --git a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md index 1ba35adf80..caa448a14a 100644 --- a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md +++ b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md @@ -54,7 +54,7 @@ context.Services.Replace( ## 重写一个服务类 -大多数情况下,你会仅想改变服务当前实现的一个或几个方法. 重新实现完整的接口变的繁琐,更好的方法是继承原始类并重写方法。 +大多数情况下,你会仅想改变服务当前实现的一个或几个方法. 重新实现完整的接口变的繁琐,更好的方法是继承原始类并重写方法. ### 示例: 重写服务方法 diff --git a/docs/zh-Hans/Entities.md b/docs/zh-Hans/Entities.md index 1a059e477f..fd8528dc30 100644 --- a/docs/zh-Hans/Entities.md +++ b/docs/zh-Hans/Entities.md @@ -72,7 +72,7 @@ public class BookAppService : ApplicationService, IBookAppService * `BookAppService` 注入图书实体的默认[仓库](Repositories.md),使用`InsertAsync`方法插入 `Book` 到数据库中. * `GuidGenerator`类型是 `IGuidGenerator`,它是在`ApplicationService`基类中定义的属性. ABP将这样常用属性预注入,所以不需要手动[注入](Dependency-Injection.md). -* 如果您想遵循DDD最佳实践,请参阅下面的*聚合示例*部分. +* 如果你想遵循DDD最佳实践,请参阅下面的*聚合示例*部分. ### 具有复合键的实体 @@ -228,7 +228,7 @@ ABP框架不强制你应用任何DDD规则或模式.但是,当你准备应用的 ## 基类和接口的审计属性 -有一些属性,像`CreationTime`,`CreatorId`,`LastModificationTime`...在所有应用中都很常见. ABP框架提供了一些接口和基类来**标准化**这些属性,并**自动设置它们的值**. +有一些属性,像`CreationTime`,`CreatorId`,`LastModificationTime`...在所有应用中都很常见. ABP框架提供了一些接口和基类来**标准化**这些属性,并**自动设置它们的值**. ### 审计接口 @@ -285,7 +285,7 @@ ABP框架不强制你应用任何DDD规则或模式.但是,当你准备应用的 所有这些基类都有非泛型版本,可以使用 `AuditedEntity` 和 `FullAuditedAggregateRoot` 来支持复合主键; -所有这些基类也有 `... WithUser`,像 `FullAuditedAggregateRootWithUser` 和 `FullAuditedAggregateRootWithUser`. 这样就可以将导航属性添加到你的用户实体. 但在聚合根之间添加导航属性不是一个好做法,所以这种用法是不建议的(除非你使用EF Core之类的ORM可以很好地支持这种情况,并且你真的需要它. 请记住这种方法不适用于NoSQL数据库(如MongoDB),你必须真正实现聚合模式). +所有这些基类也有 `... WithUser`,像 `FullAuditedAggregateRootWithUser` 和 `FullAuditedAggregateRootWithUser`. 这样就可以将导航属性添加到你的用户实体. 但在聚合根之间添加导航属性不是一个好做法,所以这种用法是不建议的(除非你使用EF Core之类的ORM可以很好地支持这种情况,并且你真的需要它. 请记住这种方法不适用于NoSQL数据库(如MongoDB),你必须真正实现聚合模式). ## 额外的属性 diff --git a/docs/zh-Hans/Entity-Framework-Core-Migrations.md b/docs/zh-Hans/Entity-Framework-Core-Migrations.md index caef6e76f2..caf5778753 100644 --- a/docs/zh-Hans/Entity-Framework-Core-Migrations.md +++ b/docs/zh-Hans/Entity-Framework-Core-Migrations.md @@ -1,7 +1,7 @@  # EF Core数据库迁移 -本文首先介绍[应用程序启动模板](Startup-Templates/Application.md)提供的**默认结构**,并讨论您可能希望为自己的应用程序实现的**各种场景**. +本文首先介绍[应用程序启动模板](Startup-Templates/Application.md)提供的**默认结构**,并讨论你可能希望为自己的应用程序实现的**各种场景**. > 本文档适用于希望完全理解和自定义[应用程序启动模板](Startup-Templates/Application.md)附带的数据库结构的人员. 如果你只是想创建实体和管理代码优先(code first)迁移,只需要遵循[启动教程](Tutorials/Index.md). @@ -95,7 +95,7 @@ Volo.Abp.IdentityServer.AbpIdentityServerDbProperties.DbTablePrefix = "Ids"; 这个项目有应用程序的 `DbContext`类(本例中的 `BookStoreDbContex` ). -**每个模块都使用自己的 `DbContext` 类**来访问数据库。同样你的应用程序有它自己的 `DbContext`. 通常在应用程序中使用这个 `DbContet`(如果你遵循最佳实践,应该在[仓储](Repositories.md)中使用). 它几乎是一个空的 `DbContext`,因为你的应用程序在一开始没有任何实体,除了预定义的 `AppUser` 实体: +**每个模块都使用自己的 `DbContext` 类**来访问数据库.同样你的应用程序有它自己的 `DbContext`. 通常在应用程序中使用这个 `DbContet`(如果你遵循最佳实践,应该在[仓储](Repositories.md)中使用). 它几乎是一个空的 `DbContext`,因为你的应用程序在一开始没有任何实体,除了预定义的 `AppUser` 实体: ````csharp [ConnectionStringName("Default")] @@ -268,10 +268,10 @@ public class BackgroundJobsDbContext ##### 重用模块的表 -您可能想在应用程序中**重用依赖模块的表**. 在这种情况下你有两个选择: +你可能想在应用程序中**重用依赖模块的表**. 在这种情况下你有两个选择: 1. 你可以**直接使用模块定义的实体**(你仍然可以在某种程度上[扩展实体](Customizing-Application-Modules-Extending-Entities.md)). -2. 你可以**创建一个新的实体**映射到同一个数据库表。 +2. 你可以**创建一个新的实体**映射到同一个数据库表. ###### 使用由模块定义的实体 @@ -307,7 +307,7 @@ namespace Acme.BookStore 示例注入了 `IRepository`(默认仓储). 它定义了标准的存储库方法并实现了 `IQueryable` 接口. -另外,身份模块定义了 `IIdentityUserRepository`(自定义仓储),你的应用程序也可以注入和使用它. `IIdentityUserRepository` 为 `IdentityUser` 实体提供了额外的定制方法,但它没有实现 `IQueryable`. +另外,身份模块定义了 `IIdentityUserRepository`(自定义仓储),你的应用程序也可以注入和使用它. `IIdentityUserRepository` 为 `IdentityUser` 实体提供了额外的定制方法,但它没有实现 `IQueryable`. ###### 创建一个新的实体 @@ -352,7 +352,7 @@ namespace Acme.BookStore.Roles * 它继承了[`AggregateRoot`类](Entities.md)和实现了[`IMultiTenant`]接口(Multi-Tenancy.md),因为 `IdentityRole` 也做了同样的继承. * 你可以添加 `IdentityRole` 实体定义的任何属性. 本例只加了 `TenantId` 和 `Name` 属性,因为我们这里只需要它们. 你可以把setters设置为私有(如同本例)以防意外更改身份模块的属性. * 你可以添加自定义(附加)属性. 本例添加了 `Title` 属性. -* **构造函数是私有的**,所以它不允许直接创建一个新的 `AppRole` 实体。创建角色身份模块的责任. 你可以查询角色,设置/更新自定义属性,但做为最佳实践你不应该在代码中创建和删除角色(尽管没有强制的限制). +* **构造函数是私有的**,所以它不允许直接创建一个新的 `AppRole` 实体.创建角色身份模块的责任. 你可以查询角色,设置/更新自定义属性,但做为最佳实践你不应该在代码中创建和删除角色(尽管没有强制的限制). 现在是时候定义EF Core映射. 打开应用程序的 `DbContext` (此示例中是 `BookStoreDbContext` )添加以下属性: @@ -360,7 +360,7 @@ namespace Acme.BookStore.Roles public DbSet Roles { get; set; } ```` -然后在 `OnModelCreating` 方法中配置映射(调用 `base.OnModelCreating(builder)` 之后): +然后在 `OnModelCreating` 方法中配置映射(调用 `base.OnModelCreating(builder)` 之后): ````csharp protected override void OnModelCreating(ModelBuilder builder) diff --git a/docs/zh-Hans/Entity-Framework-Core-MySQL.md b/docs/zh-Hans/Entity-Framework-Core-MySQL.md index 5f9d8023ab..15e2205c38 100644 --- a/docs/zh-Hans/Entity-Framework-Core-MySQL.md +++ b/docs/zh-Hans/Entity-Framework-Core-MySQL.md @@ -12,12 +12,12 @@ ## UseMySQL() -查找你的解决方案中 `UseSqlServer()`调用,替换为 `UseMySQL()`. 检查下列文件: +查找你的解决方案中 `UseSqlServer()`调用,替换为 `UseMySQL()`. 检查下列文件: * `.EntityFrameworkCore` 项目中的*YourProjectName*EntityFrameworkCoreModule.cs. * `.EntityFrameworkCore` 项目中的*YourProjectName*MigrationsDbContextFactory.cs. -> 根据你的解决方案的结构,你可能发现更多需要改变代码的文件. +> 根据你的解决方案的结构,你可能发现更多需要改变代码的文件. ## 更改连接字符串 @@ -27,7 +27,7 @@ MySQL连接字符串与SQL Server连接字符串不同. 所以检查你的解决 ## 更改迁移DbContext -MySQL DBMS与SQL Server有一些细微的差异. 某些模块数据库映射配置(尤其是字段长度)会导致MySQL出现问题. 例如某些[IdentityServer模块](Modules/IdentityServer.md)表就存在这样的问题,它提供了一个选项可以根据您的DBMS配置字段. +MySQL DBMS与SQL Server有一些细微的差异. 某些模块数据库映射配置(尤其是字段长度)会导致MySQL出现问题. 例如某些[IdentityServer模块](Modules/IdentityServer.md)表就存在这样的问题,它提供了一个选项可以根据你的DBMS配置字段. 启动模板包含*YourProjectName*MigrationsDbContext,它负责维护和迁移数据库架构. 此DbContext基本上调用依赖模块的扩展方法来配置其数据库表. diff --git a/docs/zh-Hans/Entity-Framework-Core-Other-DBMS.md b/docs/zh-Hans/Entity-Framework-Core-Other-DBMS.md index ca12d7524f..ca70d8b5c6 100644 --- a/docs/zh-Hans/Entity-Framework-Core-Other-DBMS.md +++ b/docs/zh-Hans/Entity-Framework-Core-Other-DBMS.md @@ -63,7 +63,7 @@ MySQL连接字符串与SQL Server连接字符串不同. 所以检查你的解决 ## 更改迁移DbContext -MySQL DBMS与SQL Server有一些细微的差异. 某些模块数据库映射配置(尤其是字段长度)会导致MySQL出现问题. 例如某些[IdentityServer模块](Modules/IdentityServer.md)表就存在这样的问题,它提供了一个选项可以根据您的DBMS配置字段. +MySQL DBMS与SQL Server有一些细微的差异. 某些模块数据库映射配置(尤其是字段长度)会导致MySQL出现问题. 例如某些[IdentityServer模块](Modules/IdentityServer.md)表就存在这样的问题,它提供了一个选项可以根据你的DBMS配置字段. 启动模板包含*YourProjectName*MigrationsDbContext,它负责维护和迁移数据库架构. 此DbContext基本上调用依赖模块的扩展方法来配置其数据库表. diff --git a/docs/zh-Hans/Entity-Framework-Core-PostgreSQL.md b/docs/zh-Hans/Entity-Framework-Core-PostgreSQL.md index bb1de20207..08f8f405d1 100644 --- a/docs/zh-Hans/Entity-Framework-Core-PostgreSQL.md +++ b/docs/zh-Hans/Entity-Framework-Core-PostgreSQL.md @@ -12,12 +12,12 @@ ## UsePostgreSql() -查找你的解决方案中 `UseSqlServer()`调用,替换为 `UsePostgreSql()`. 检查下列文件: +查找你的解决方案中 `UseSqlServer()`调用,替换为 `UsePostgreSql()`. 检查下列文件: * `.EntityFrameworkCore` 项目中的*YourProjectName*EntityFrameworkCoreModule.cs. * `.EntityFrameworkCore` 项目中的*YourProjectName*MigrationsDbContextFactory.cs. -> 根据你的解决方案的结构,你可能发现更多需要改变代码的文件. +> 根据你的解决方案的结构,你可能发现更多需要改变代码的文件. ## 更改连接字符串 diff --git a/docs/zh-Hans/Entity-Framework-Core-SQLite.md b/docs/zh-Hans/Entity-Framework-Core-SQLite.md index 4b8e009fe4..d75f8ba5b7 100644 --- a/docs/zh-Hans/Entity-Framework-Core-SQLite.md +++ b/docs/zh-Hans/Entity-Framework-Core-SQLite.md @@ -12,12 +12,12 @@ ## UseSqlite() -查找你的解决方案中 `UseSqlServer()`调用,替换为 `UseSqlite()`. 检查下列文件: +查找你的解决方案中 `UseSqlServer()`调用,替换为 `UseSqlite()`. 检查下列文件: * `.EntityFrameworkCore` 项目中的*YourProjectName*EntityFrameworkCoreModule.cs. * `.EntityFrameworkCore` 项目中的*YourProjectName*MigrationsDbContextFactory.cs. -> 根据你的解决方案的结构,你可能发现更多需要改变代码的文件. +> 根据你的解决方案的结构,你可能发现更多需要改变代码的文件. ## 更改连接字符串 diff --git a/docs/zh-Hans/Entity-Framework-Core.md b/docs/zh-Hans/Entity-Framework-Core.md index d2af31f4d2..5ae6ce1070 100644 --- a/docs/zh-Hans/Entity-Framework-Core.md +++ b/docs/zh-Hans/Entity-Framework-Core.md @@ -108,7 +108,7 @@ protected override void OnModelCreating(ModelBuilder builder) ### 配置连接字符串选择 如果你的应用程序有多个数据库,你可以使用 `connectionStringName]` Attribute为你的DbContext配置连接字符串名称. -例: +例: ```csharp [ConnectionStringName("MySecondConnString")] @@ -274,7 +274,7 @@ public override async Task DeleteAsync( ## 访问 EF Core API -大多数情况下应该隐藏仓储后面的EF Core API(这也是仓储的设计目地). 但是如果想要通过仓储访问DbContext实现,则可以使用`GetDbContext()`或`GetDbSet()`扩展方法. 例: +大多数情况下应该隐藏仓储后面的EF Core API(这也是仓储的设计目地). 但是如果想要通过仓储访问DbContext实现,则可以使用`GetDbContext()`或`GetDbSet()`扩展方法. 例: ````csharp public class BookService @@ -304,7 +304,7 @@ public class BookService 默认,实体的所有额外属性存储在数据库的一个 `JSON` 对象中. -实体扩展系统允许你存储额外属性在数据库的单独字段中. 有关额外属性和实体扩展系统的更多信息,请参阅下列文档: +实体扩展系统允许你存储额外属性在数据库的单独字段中. 有关额外属性和实体扩展系统的更多信息,请参阅下列文档: * [自定义应用模块: 扩展实体](Customizing-Application-Modules-Extending-Entities.md) * [实体](Entities.md) @@ -313,7 +313,7 @@ public class BookService ### ObjectExtensionManager.Instance -`ObjectExtensionManager` 实现单例模式,因此你需要使用静态的 `ObjectExtensionManager.Instance` 来执行所有操作。 +`ObjectExtensionManager` 实现单例模式,因此你需要使用静态的 `ObjectExtensionManager.Instance` 来执行所有操作. ### MapEfCoreProperty @@ -417,7 +417,7 @@ context.Services.AddAbpDbContext(options => }); ```` -现在,您的自定义仓储也可以使用`IBookStoreDbContext`接口: +现在,你的自定义仓储也可以使用`IBookStoreDbContext`接口: ````csharp public class BookRepository : EfCoreRepository, IBookRepository diff --git a/docs/zh-Hans/Getting-Started-AspNetCore-Application.md b/docs/zh-Hans/Getting-Started-AspNetCore-Application.md index 370e99c091..46348ecbdf 100644 --- a/docs/zh-Hans/Getting-Started-AspNetCore-Application.md +++ b/docs/zh-Hans/Getting-Started-AspNetCore-Application.md @@ -156,7 +156,7 @@ services.AddApplication(options => }); ```` -4. 更新 `Program.cs`代码, 不再使用`WebHost.CreateDefaultBuilder()`方法(因为它使用默认的DI容器): +4. 更新 `Program.cs`代码, 不再使用`WebHost.CreateDefaultBuilder()`方法(因为它使用默认的DI容器): ````csharp public class Program diff --git a/docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md b/docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md index 90291e968f..2778f3db42 100644 --- a/docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md +++ b/docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md @@ -4,7 +4,7 @@ 本教程使用 **ABP CLI** 创建一个新项目. 更多选项, 请参阅[入门](https://abp.io/get-started)页面. -如果你之前未安装,请使用命令行安装ABP CLI: +如果你之前未安装,请使用命令行安装ABP CLI: ````bash dotnet tool install -g Volo.Abp.Cli diff --git a/docs/zh-Hans/Index.md b/docs/zh-Hans/Index.md index d946d8f0bb..71e5a520da 100644 --- a/docs/zh-Hans/Index.md +++ b/docs/zh-Hans/Index.md @@ -12,7 +12,7 @@ ABP是一个**开源应用程序框架**,专注于基于ASP.NET Core的Web应用 * [ASP.NET Core MVC 模板](Getting-Started-AspNetCore-MVC-Template.md) -如果您想从头开始(使用空项目),请手动安装ABP框架并使用以下教程: +如果你想从头开始(使用空项目),请手动安装ABP框架并使用以下教程: * [控制台应用程序](Getting-Started-Console-Application.md) * [ASP.NET Core Web 应用程序](Getting-Started-AspNetCore-Application.md) diff --git a/docs/zh-Hans/Modules/Docs.md b/docs/zh-Hans/Modules/Docs.md index 20382d24f2..96452f2bd5 100644 --- a/docs/zh-Hans/Modules/Docs.md +++ b/docs/zh-Hans/Modules/Docs.md @@ -326,7 +326,7 @@ There are no projects yet! {"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/zh-Hans/","GitHubAccessToken":"***","GitHubUserAgent":""} ``` - 注意 `GitHubAccessToken` 用 `***` 掩盖. 这是一个私人令牌,你必须从GitHub获取它. 请参阅 https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + 注意 `GitHubAccessToken` 用 `***` 掩盖. 这是一个私人令牌,你必须从GitHub获取它. 请参阅 https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ - MainWebsiteUrl: `/` @@ -338,7 +338,7 @@ There are no projects yet! INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName], [ParametersDocumentName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939658', N'ABP framework (GitHub)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'GitHub', N'{"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs","GitHubAccessToken":"***","GitHubUserAgent":""}', N'/', N'master', N'') ``` -请注意,`GitHubAccessToken` 被屏蔽了.它是一个私人令牌,你必须获得自己的令牌并替换 `***` 字符串. +请注意,`GitHubAccessToken` 被屏蔽了.它是一个私人令牌,你必须获得自己的令牌并替换 `***` 字符串. 现在你可以运行应用程序并导航到 `/Documents`. @@ -378,9 +378,9 @@ INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocume INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName], [ParametersDocumentName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939659', N'ABP framework (FileSystem)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'FileSystem', N'{"Path":"C:\\Github\\abp\\docs"}', N'/', NULL, N'') ``` -添加上面的一个示例项目后运行该应用程序. 在菜单中你会看到`文档` 链接,点击菜单链接打开文档页面. +添加上面的一个示例项目后运行该应用程序. 在菜单中你会看到`文档` 链接,点击菜单链接打开文档页面. -到目前为止, 我们已经从abp.io网站创建了一个新的应用程序,并为Docs模块做好准备. +到目前为止, 我们已经从abp.io网站创建了一个新的应用程序,并为Docs模块做好准备. ### 7- 添加一个新文档 @@ -454,7 +454,7 @@ public class Person } ``` -因为并不是项目中的每个文档都有章节或者不需要所有的参数,你必须声明哪些参数将用于对文档进行分段,在文档的任何地方都可以使用JSON块. +因为并不是项目中的每个文档都有章节或者不需要所有的参数,你必须声明哪些参数将用于对文档进行分段,在文档的任何地方都可以使用JSON块. 例如 [Getting-Started.md](https://github.com/abpio/abp-commercial-docs/blob/master/en/getting-started.md): @@ -570,7 +570,7 @@ This document assumes that you prefer to use **{{ UI_Value }}** as the UI framew ![Navigation menu](../images/docs-module_download-sample-navigation-menu.png) -最后,为您的项目添加了一个新的Docs模块, 该模块由GitHub提供. +最后,为你的项目添加了一个新的Docs模块, 该模块由GitHub提供. ## 全文搜索(Elastic Search) diff --git a/docs/zh-Hans/Object-Extensions.md b/docs/zh-Hans/Object-Extensions.md index 27957708f4..a0f1e5534b 100644 --- a/docs/zh-Hans/Object-Extensions.md +++ b/docs/zh-Hans/Object-Extensions.md @@ -62,7 +62,7 @@ if (user.GetProperty("IsSuperUser")) ##### 非基本属性类型 -如果您的属性类型不是原始类型(int,bool,枚举,字符串等),你需要使用 `GetProperty` 的非泛型版本,它会返回 `object`. +如果你的属性类型不是原始类型(int,bool,枚举,字符串等),你需要使用 `GetProperty` 的非泛型版本,它会返回 `object`. #### HasProperty @@ -180,7 +180,7 @@ ObjectExtensionManager.Instance 假设你已向可扩展的实体对象添加了额外的属性并使用了自动[对象到对象的映射](Object-To-Object-Mapping.md)将该实体映射到可扩展的DTO类. 在这种情况下你需要格外小心,因为额外属性可能包含**敏感数据**,这些数据对于客户端不可用. -本节提供了一些**好的做法**,可以控制对象映射的额外属性。 +本节提供了一些**好的做法**,可以控制对象映射的额外属性. ### MapExtraPropertiesTo @@ -232,7 +232,7 @@ identityUser.MapExtraPropertiesTo( #### AutoMapper集成 -如果您使用的是[AutoMapper](https://automapper.org/)库,ABP框架还提供了一种扩展方法来利用上面定义的 `MapExtraPropertiesTo` 方法. +如果你使用的是[AutoMapper](https://automapper.org/)库,ABP框架还提供了一种扩展方法来利用上面定义的 `MapExtraPropertiesTo` 方法. 你可以在映射配置文件中使用 `MapExtraProperties()` 方法. @@ -247,7 +247,7 @@ public class MyProfile : Profile } ```` -它与 `MapExtraPropertiesTo()` 方法具有相同的参数。 +它与 `MapExtraPropertiesTo()` 方法具有相同的参数. ## Entity Framework Core 数据库映射 diff --git a/docs/zh-Hans/Object-To-Object-Mapping.md b/docs/zh-Hans/Object-To-Object-Mapping.md index 57b744e0bf..1b60112cb2 100644 --- a/docs/zh-Hans/Object-To-Object-Mapping.md +++ b/docs/zh-Hans/Object-To-Object-Mapping.md @@ -168,7 +168,7 @@ public class MyProfile : Profile 假设你已经创建了一个**可重用的模块**,其中定义了AutoMapper配置文件,并在需要映射对象时使用 `IObjectMapper`. 根据[模块化](Module-Development-Basics.md)的性质,你的模块可以用于不同的应用程序. -`IObjectMapper` 是一个抽象,可以由最终应用程序替换使用另一个映射库. 这里的问题是你的可重用模块设计为使用AutoMapper,因为它为其定义映射配置文件. 这种情况下即使最终应用程序使用另一个默认对象映射库,你也要保证模块始终使用AutoMapper. +`IObjectMapper` 是一个抽象,可以由最终应用程序替换使用另一个映射库. 这里的问题是你的可重用模块设计为使用AutoMapper,因为它为其定义映射配置文件. 这种情况下即使最终应用程序使用另一个默认对象映射库,你也要保证模块始终使用AutoMapper. `IObjectMapper`将对象映射器上下文化,你可以为不同的 模块/上下文 使用不同的库. @@ -201,7 +201,7 @@ public class UserAppService : ApplicationService `UserAppService` 注入 `IObjectMapper`, 它是模块的特定对象映射器,用法与 `IObjectMapper` 完全相同. -上面的示例代码未使用 `ApplicationService` 中定义的 `ObjectMapper` 属性,而是注入了 `IObjectMapper`. 但是 `ApplicationService` 定义了可以在类构造函数中设置的 `ObjectMapperContext` 属性, 因此仍然可以使用基类属性. 示例可以进行以下重写: +上面的示例代码未使用 `ApplicationService` 中定义的 `ObjectMapper` 属性,而是注入了 `IObjectMapper`. 但是 `ApplicationService` 定义了可以在类构造函数中设置的 `ObjectMapperContext` 属性, 因此仍然可以使用基类属性. 示例可以进行以下重写: ````csharp public class UserAppService : ApplicationService diff --git a/docs/zh-Hans/Options.md b/docs/zh-Hans/Options.md index 18ccd90bed..c88ff0adda 100644 --- a/docs/zh-Hans/Options.md +++ b/docs/zh-Hans/Options.md @@ -9,7 +9,7 @@ ABP框架遵循选项模式,并定义了用于配置框架和模块的选项类( ## 配置选项 通常配置选项在 `Startup` 类的 `ConfigureServices` 方法中. 但由于ABP框架提供了模块化基础设施,因此你可以在[模块](Module-Development-Basics.md)的`ConfigureServices` 方法配置选项. -例: +例: ````csharp public override void ConfigureServices(ServiceConfigurationContext context) @@ -34,7 +34,7 @@ public class MyOptions } ```` -然后开发人员可以像上面 `AbpAuditingOptions` 示例一样配置你的选项: +然后开发人员可以像上面 `AbpAuditingOptions` 示例一样配置你的选项: ````csharp public override void ConfigureServices(ServiceConfigurationContext context) @@ -80,9 +80,9 @@ public class MyService : ITransientDependency 如果你正在开发一个模块,可能需要让开发者能够设置一些选项,并在依赖注入注册阶段使用这些选项. 你可能需要根据选项值配置其他服务或更改依赖注入的注册代码. -对于此类情况,ABP为 `IServiceCollection` 引入了 `PreConfigure` 和 `ExecutePreConfiguredActions` 扩展方法. 该模式的工作原理如下所述。 +对于此类情况,ABP为 `IServiceCollection` 引入了 `PreConfigure` 和 `ExecutePreConfiguredActions` 扩展方法. 该模式的工作原理如下所述. -1. 你的模块中定义计划选项类. 例: +1. 你的模块中定义计划选项类. 例: ````csharp public class MyPreOptions @@ -92,7 +92,7 @@ public class MyPreOptions ```` 然后任何依赖于模块的模块类都可以在其 `PreConfigureServices` 方法中使用 `PreConfigure` 方法. -例: +例: ````csharp public override void PreConfigureServices(ServiceConfigurationContext context) diff --git a/docs/zh-Hans/Samples/Microservice-Demo.md b/docs/zh-Hans/Samples/Microservice-Demo.md index 9b559797f7..40cb42cda6 100644 --- a/docs/zh-Hans/Samples/Microservice-Demo.md +++ b/docs/zh-Hans/Samples/Microservice-Demo.md @@ -51,13 +51,13 @@ ABP框架的主要目标之一就是提供[便捷的基础设施来创建微服 ### 创建数据库 -MongoDB 数据库是动态创建的,但是你需要创建 SQL server 数据库的结构。其实你可以很轻松的创建数据库,因为这个解决方案配置了使用 Entity Core Code First 来做迁移。 +MongoDB 数据库是动态创建的,但是你需要创建 SQL server 数据库的结构.其实你可以很轻松的创建数据库,因为这个解决方案配置了使用 Entity Core Code First 来做迁移. -这个解决方案中有两个 SQL server 数据库。 +这个解决方案中有两个 SQL server 数据库. #### MsDemo_Identity 数据库 -* 右键 `AuthServer.Host` 项目,然后点击 `设置为启动项目`. +* 右键 `AuthServer.Host` 项目,然后点击 `设置为启动项目`. * 打开 **程序包管理器控制台** (工具 -> NuGet 包管理器 -> 程序包管理器控制台) * 选择 `AuthServer.Host` 成为 **默认项目**. * 执行 `Update-Database` 命令. @@ -66,7 +66,7 @@ MongoDB 数据库是动态创建的,但是你需要创建 SQL server 数据库 #### MsDemo_ProductManagement -* 右键 `ProductService.Host` 项目,然后点击 `设置为启动项目`. +* 右键 `ProductService.Host` 项目,然后点击 `设置为启动项目`. * 打开 **程序包管理器控制台** (工具 -> NuGet 包管理器 -> 程序包管理器控制台) * 选择 `ProductService.Host` 成为 **默认项目**. * 执行 `Update-Database` 命令. @@ -334,7 +334,7 @@ context.Services.AddAuthentication(options => - 它需要额外的身份范围 *role*, *email* and *phone*. - 它需要API资源范围 *PublicWebSiteGateway*,*BloggingService*和*ProductService*,因为它将这些服务用作API. -IdentityServer客户端设置存储在`appsettings.json`文件中: +IdentityServer客户端设置存储在`appsettings.json`文件中: ```json "AuthServer": { @@ -348,7 +348,7 @@ IdentityServer客户端设置存储在`appsettings.json`文件中: PublicWebSite.Host项目有一个列出产品的页面 (`Pages/Products.cshtml`). 它还使用博客模块中的UI. 为此`PublicWebSiteHostModule`加入了`BloggingWebModule`(*[Volo.Blogging.Web](https://www.nuget.org/packages/Volo.Blogging.Web)* 包)的依赖项. -产品页面的屏幕截图: +产品页面的屏幕截图: ![microservice-sample-public-product-list](../images/microservice-sample-public-product-list.png) @@ -390,7 +390,7 @@ PublicWebSite.Host项目有一个列出产品的页面 (`Pages/Products.cshtml`) #### 远程服务配置 -`appsettings.json`文件中的`RemoteService`配置很简单: +`appsettings.json`文件中的`RemoteService`配置很简单: ````json "RemoteServices": { @@ -418,7 +418,7 @@ PublicWebSite.Host项目有一个列出产品的页面 (`Pages/Products.cshtml`) } ```` -此示例使用`client_credentials` 授予类型,该类型需要`ClientId`和`ClientSecret`进行身份验证过程. 还有[其他授予类型](http://docs.identityserver.io/en/latest/topics/grant_types.html). 例如, 你可以使用以下配置切换到`password`(Resource Owner Password)授予类型: +此示例使用`client_credentials` 授予类型,该类型需要`ClientId`和`ClientSecret`进行身份验证过程. 还有[其他授予类型](http://docs.identityserver.io/en/latest/topics/grant_types.html). 例如, 你可以使用以下配置切换到`password`(Resource Owner Password)授予类型: ````json "IdentityClients": { @@ -571,7 +571,7 @@ app.UseOcelot().Wait(); #### 权限管理 -后端管理应用程序提供权限管理UI(之前见过),并使用此网关获取/设置权限. 权限管理API托管在网关内,而不是单独的服务. 这是一个设计决策,但如果您愿意,它可以作为另一个微服务托管. +后端管理应用程序提供权限管理UI(之前见过),并使用此网关获取/设置权限. 权限管理API托管在网关内,而不是单独的服务. 这是一个设计决策,但如果你愿意,它可以作为另一个微服务托管. #### Dependencies @@ -1229,7 +1229,7 @@ public class ProductCodeAlreadyExistsException : BusinessException } ```` -`PM:000001`是发送给客户端的异常类型的代码,因此他们可以理解错误类型. 在这种情况下没有实现,但也可以本地化业务异常. 请参阅[异常处理文档](../Exception-Handling.md). +`PM:000001`是发送给客户端的异常类型的代码,因此他们可以理解错误类型. 在这种情况下没有实现,但也可以本地化业务异常. 请参阅[异常处理文档](../Exception-Handling.md). #### 应用层 @@ -1278,7 +1278,7 @@ public async Task UpdateAsync(Guid id, UpdateProductDto input) 分布式事件(事件总线)是一种消息传递方式,其中服务引发/触发事件,而其他服务注册/侦听这些事件,以便在发生重要事件时得到通知. ABP通过提供约定,服务和集成使分布式事件更易于使用. -您已经看到`Product`类使用以下代码行发布事件: +你已经看到`Product`类使用以下代码行发布事件: ````csharp AddDistributedEvent(new ProductStockCountChangedEto(Id, StockCount, stockCount)); @@ -1406,7 +1406,7 @@ Kibana URL默认为`http://localhost:5601/`. ABP提供自动审计日志记录,详细保存每个请求(当前用户,浏览器/客户端,执行了哪些操作,哪些实体更改,甚至实体的哪些属性已更新). 有关详细信息,请参阅[审计日志文档](../Audit-Logging.md). -所有服务和应用程序都配置为编写审核日志. 审核日志将保存到MsDemo_Identity SQL数据库中. 因此,您可以从单个点查询所有应用程序的所有审核日志. +所有服务和应用程序都配置为编写审核日志. 审核日志将保存到MsDemo_Identity SQL数据库中. 因此,你可以从单个点查询所有应用程序的所有审核日志. 审核日志记录具有`CorrelationId`属性,可用于跟踪请求. 当服务在单个Web请求中调用另一个服务时,它们都会使用相同的`CorrelationId`保存审核日志. 请参阅数据库中的`AbpAuditLogs`表. diff --git a/docs/zh-Hans/Settings.md b/docs/zh-Hans/Settings.md index 25559082f2..a4d84c91b7 100644 --- a/docs/zh-Hans/Settings.md +++ b/docs/zh-Hans/Settings.md @@ -226,6 +226,6 @@ Configure(options => ## 设置管理模块 -设置系统核心是相当独立的,不做任何关于如何管理(更改)设置值的假设. 默认的`ISettingStore`实现也是`NullSettingStore`,它为所有设置值返回null. +设置系统核心是相当独立的,不做任何关于如何管理(更改)设置值的假设. 默认的`ISettingStore`实现也是`NullSettingStore`,它为所有设置值返回null. 设置管理模块通过管理数据库中的设置值来完成逻辑(实现`ISettingStore`).有关更多信息参阅[设置管理模块](Modules/Setting-Management.md)学习更多. diff --git a/docs/zh-Hans/Startup-Templates/Application.md b/docs/zh-Hans/Startup-Templates/Application.md index 31453ff728..4e2c3f6700 100644 --- a/docs/zh-Hans/Startup-Templates/Application.md +++ b/docs/zh-Hans/Startup-Templates/Application.md @@ -348,7 +348,7 @@ Home模块是一个可延迟加载的模块, 它加载应用程序的根地址. React 本机应用程序是用 [Expo](https://expo.io/)生成的. Expo 是一套基于 React Native 构建的工具, 帮助你快速启动一个应用程序, 尽管它有很多功能. -React Native 应用文件夹结构, 如下图所示: +React Native 应用文件夹结构, 如下图所示: ![react-native-folder-structure](../images/react-native-folder-structure.png) @@ -380,7 +380,7 @@ Screens 是通过在 `src/screens` 文件夹中创建将名称分开的文件夹 [Redux](https://redux.js.org/) 被用作状态管理库. [Redux Toolkit](https://redux-toolkit.js.org/) 库被用作高效Redux开发的工具集. -在 `src/store` 文件夹中创建 Actions, reducers, sagas, selectors. 存储文件夹如下: +在 `src/store` 文件夹中创建 Actions, reducers, sagas, selectors. 存储文件夹如下: ![react-native-store-folder](../images/react-native-store-folder.png) diff --git a/docs/zh-Hans/Startup-Templates/Index.md b/docs/zh-Hans/Startup-Templates/Index.md index 57389e6df0..160a2b3e20 100644 --- a/docs/zh-Hans/Startup-Templates/Index.md +++ b/docs/zh-Hans/Startup-Templates/Index.md @@ -2,7 +2,7 @@ 虽然你可以从一个空项目开始并手动添加所需的包,但启动模板可以非常轻松,舒适地使用ABP框架启动新的解决方案. -单击下面列表中的名称以查看相关启动模板的文档: +单击下面列表中的名称以查看相关启动模板的文档: * [**app**](Application.md): 应用程序模板. * [**module**](Module.md): 模块/服务模板. \ No newline at end of file diff --git a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md index e1cbb73cc1..7c2db90997 100644 --- a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md +++ b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md @@ -33,7 +33,7 @@ - `Acme.BookStore.Domain`包含你的[实体](https://docs.abp.io/zh-Hans/abp/latest/Entities), [领域服务](https://docs.abp.io/zh-Hans/abp/latest/Domain-Services)和其他核心域对象. - `Acme.BookStore.Domain.Shared`包含可与客户共享的常量,枚举或其他域相关对象. -在解决方案的**领域层**(`Acme.BookStore.Domain`项目)中定义[实体](https://docs.abp.io/zh-Hans/abp/latest/Entities). 该应用程序的主要实体是`Book`. 在`Acme.BookStore.Domain`项目中创建一个名为`Book`的类,如下所示: +在解决方案的**领域层**(`Acme.BookStore.Domain`项目)中定义[实体](https://docs.abp.io/zh-Hans/abp/latest/Entities). 该应用程序的主要实体是`Book`. 在`Acme.BookStore.Domain`项目中创建一个名为`Book`的类,如下所示: ````C# using System; @@ -132,7 +132,7 @@ PM> Update-Database #### 添加示例数据 -`Update-Database`命令在数据库中创建了`AppBooks`表. 打开数据库并输入几个示例行,以便在页面上显示它们: +`Update-Database`命令在数据库中创建了`AppBooks`表. 打开数据库并输入几个示例行,以便在页面上显示它们: ![bookstore-books-table](images/bookstore-books-table.png) @@ -290,7 +290,7 @@ namespace Acme.BookStore #### Swagger UI -启动模板配置为使用[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)运行[swagger UI](https://swagger.io/tools/swagger-ui/). 运行应用程序并在浏览器中输入`https://localhost:XXXX/swagger/`(用您自己的端口替换XXXX)作为URL. +启动模板配置为使用[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)运行[swagger UI](https://swagger.io/tools/swagger-ui/). 运行应用程序并在浏览器中输入`https://localhost:XXXX/swagger/`(用你自己的端口替换XXXX)作为URL. 你会看到一些内置的接口和`Book`的接口,它们都是REST风格的: @@ -380,7 +380,7 @@ context.Menu.AddItem( ![bookstore-localization-files](images/bookstore-localization-files-v2.png) -打开`en.json`文件,将`Menu:BookStore`和`Menu:Books`键的本地化文本添加到文件末尾: +打开`en.json`文件,将`Menu:BookStore`和`Menu:Books`键的本地化文本添加到文件末尾: ````json { diff --git a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md index a5e51134fa..e072e5a1a7 100644 --- a/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md +++ b/docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md @@ -14,7 +14,7 @@ ### 解决方案中的测试项目 -解决方案中有多个测试项目: +解决方案中有多个测试项目: ![bookstore-test-projects-v2](images/bookstore-test-projects-v2.png) @@ -68,7 +68,7 @@ namespace Acme.BookStore ```` * 注入`IRepository`并在`SeedAsync`中使用它来创建两个书实体作为测试数据. -* 使用`IGuidGenerator`服务创建GUID. 虽然`Guid.NewGuid()`非常适合测试,但`IGuidGenerator`在使用真实数据库时还有其他特别重要的功能(参见[Guid生成文档](../../../Guid-Generation.md)了解更多信息). +* 使用`IGuidGenerator`服务创建GUID. 虽然`Guid.NewGuid()`非常适合测试,但`IGuidGenerator`在使用真实数据库时还有其他特别重要的功能(参见[Guid生成文档](../../../Guid-Generation.md)了解更多信息). ### 测试 BookAppService diff --git a/docs/zh-Hans/UI/Angular/Component-Replacement.md b/docs/zh-Hans/UI/Angular/Component-Replacement.md index e98ce4331e..dc7c1a33c4 100644 --- a/docs/zh-Hans/UI/Angular/Component-Replacement.md +++ b/docs/zh-Hans/UI/Angular/Component-Replacement.md @@ -2,7 +2,7 @@ 你可以将一些ABP的组件替换为你自己的自定义组件. -您可以**替换**但**不能自定义**默认ABP组件的原因是禁用或更改该组件的一部分可能会导致问题. 所以我们把这些组件称为可替换组件. +你可以**替换**但**不能自定义**默认ABP组件的原因是禁用或更改该组件的一部分可能会导致问题. 所以我们把这些组件称为可替换组件. ### 如何替换组件 diff --git a/docs/zh-Hans/UI/Angular/Config-State.md b/docs/zh-Hans/UI/Angular/Config-State.md index 94b522f3fc..4967dd78b3 100644 --- a/docs/zh-Hans/UI/Angular/Config-State.md +++ b/docs/zh-Hans/UI/Angular/Config-State.md @@ -164,7 +164,7 @@ const hasIdentityOrAccountPermission = this.config.getGrantedPolicy( ### 如何从Store中获取翻译 -`ConfigStateService` 的 `getLocalization` 用法翻译. 这里有一些示例: +`ConfigStateService` 的 `getLocalization` 方法用于翻译. 这里有一些示例: ```js // this.config is instance of ConfigStateService @@ -186,7 +186,7 @@ const defaultValue = this.config.getLocalization({ ## 分发方法 -`ConfigStateService` 有几种分发方法,让你方便地将预定义操作分发到 `Store`. +`ConfigStateService` 有几种分发方法,让你方便地将预定义操作分发到 `Store`. ### 如何从服务器获取应用程序配置 @@ -245,7 +245,7 @@ this.config.dispatchAddRoute(newRoute); `newRoute` 将被放置在根级别,没有任何父路由,并且其url将存储为 `'/path'`. -如果你想要**添加一个子路由,您可以这样做:** +如果你想要**添加一个子路由,你可以这样做:** ```js // this.config is instance of ConfigStateService @@ -291,4 +291,4 @@ this.config.dispatchSetEnvironment({ ## 下一步是什么? -* [组件替换]](./Component-Replacement.md) \ No newline at end of file +* [组件替换](./Component-Replacement.md) \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Content-Strategy.md b/docs/zh-Hans/UI/Angular/Content-Strategy.md index 3600f2dbf4..b4430f285d 100644 --- a/docs/zh-Hans/UI/Angular/Content-Strategy.md +++ b/docs/zh-Hans/UI/Angular/Content-Strategy.md @@ -1,6 +1,6 @@ # ContentStrategy -`ContentStrategy` 是@abp/ng.core包暴露出的抽象类. 它可以帮助您创建内联脚本或样式. +`ContentStrategy` 是@abp/ng.core包暴露出的抽象类. 它可以帮助你创建内联脚本或样式. ## API diff --git a/docs/zh-Hans/UI/Angular/Context-Strategy.md b/docs/zh-Hans/UI/Angular/Context-Strategy.md index 93abfa7cef..26d8ba9270 100644 --- a/docs/zh-Hans/UI/Angular/Context-Strategy.md +++ b/docs/zh-Hans/UI/Angular/Context-Strategy.md @@ -76,7 +76,7 @@ setContext(): undefined CONTEXT_STRATEGY.None() ``` -该策略不会将任何上下文传递到投影内容。 +该策略不会将任何上下文传递到投影内容. ### Component diff --git a/docs/zh-Hans/UI/Angular/Dom-Insertion-Service.md b/docs/zh-Hans/UI/Angular/Dom-Insertion-Service.md index 197ef9255c..e8d9420422 100644 --- a/docs/zh-Hans/UI/Angular/Dom-Insertion-Service.md +++ b/docs/zh-Hans/UI/Angular/Dom-Insertion-Service.md @@ -125,6 +125,16 @@ removeContent(element: HTMLScriptElement | HTMLStyleElement): void - `element` 参数是已插入的 `HTMLScriptElement` 或 `HTMLStyleElement` 元素,它们应由 `insertContent` 方法返回. +### has + +```js +has(content: string): boolean +``` + +`has` 返回一个布尔值,用于表示给定的内容是否插入到DOM. + +- `content` 参数是 `HTMLScriptElement` 或 `HTMLStyleElement` 元素的内容. + ## 下一步是什么? - [ContentProjectionService](./Content-Projection-Service.md) \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Lazy-Load-Service.md b/docs/zh-Hans/UI/Angular/Lazy-Load-Service.md index abd08a0410..07753f8541 100644 --- a/docs/zh-Hans/UI/Angular/Lazy-Load-Service.md +++ b/docs/zh-Hans/UI/Angular/Lazy-Load-Service.md @@ -162,7 +162,7 @@ class DemoComponent { } ``` -在此示例中,第二个文件需要预先加载第一个文件, RxJS `concat` 函数将允许你以给定的顺序一个接一个地加载所有脚本,并且仅在加载所有脚本时放行. +在此示例中,第二个文件需要预先加载第一个文件, RxJS `concat` 函数将允许你以给定的顺序一个接一个地加载所有脚本,并且仅在加载所有脚本时放行. ## API diff --git a/docs/zh-Hans/UI/Angular/Permission-Management.md b/docs/zh-Hans/UI/Angular/Permission-Management.md index 1fd9c5f5d2..67ec1b787e 100644 --- a/docs/zh-Hans/UI/Angular/Permission-Management.md +++ b/docs/zh-Hans/UI/Angular/Permission-Management.md @@ -2,7 +2,7 @@ 权限是为特定用户,角色或客户端授予或禁止的简单策略. 你可以在[ABP授权文档](../../Authorization.md)中阅读更多信息. -您可以使用 `ConfigState` 的 `getGrantedPolicy` 选择器获取经过身份验证的用户的权限. +你可以使用 `ConfigState` 的 `getGrantedPolicy` 选择器获取经过身份验证的用户的权限. 你可以从Store中获取权限的布尔值: diff --git a/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md b/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md index ebb402b273..6a229714c1 100644 --- a/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md +++ b/docs/zh-Hans/UI/AspNetCore/Bundling-Minification.md @@ -234,7 +234,7 @@ public class MyExtensionStyleBundleContributor : BundleContributor #### 贡献者扩展 -在某些高级应用场景中, 当用到一个bundle贡献者时,你可能想做一些额外的配置. 贡献者扩展可以和被扩展的贡献者无缝衔接. +在某些高级应用场景中, 当用到一个bundle贡献者时,你可能想做一些额外的配置. 贡献者扩展可以和被扩展的贡献者无缝衔接. 下面的示例为 prism.js 脚本库添加一些样式: diff --git a/docs/zh-Hans/UI/AspNetCore/Tag-Helpers/Progress-Bars.md b/docs/zh-Hans/UI/AspNetCore/Tag-Helpers/Progress-Bars.md index 7865c6927a..18c896a90e 100644 --- a/docs/zh-Hans/UI/AspNetCore/Tag-Helpers/Progress-Bars.md +++ b/docs/zh-Hans/UI/AspNetCore/Tag-Helpers/Progress-Bars.md @@ -47,7 +47,7 @@ ### min-value -进度条的最小值. 默认值是0。 +进度条的最小值. 默认值是0. ### max-value diff --git a/docs/zh-Hans/Validation.md b/docs/zh-Hans/Validation.md index 8aa81351ec..f6b2daf31f 100644 --- a/docs/zh-Hans/Validation.md +++ b/docs/zh-Hans/Validation.md @@ -8,7 +8,7 @@ ABP增加了以下优点: * 定义 `IValidationEnabled` 向任意类添加自动验证. 所有的[应用服务](Application-Services.md)都实现了该接口,所以它们会被自动验证. * 自动将数据注解属性的验证错误信息本地化. -* 提供可扩展的服务来验证方法调用或对象的状态。 +* 提供可扩展的服务来验证方法调用或对象的状态. * 提供[FluentValidation](https://fluentvalidation.net/)的集成. ## 验证DTO @@ -80,7 +80,7 @@ namespace Acme.BookStore #### 解析服务 如果你需要从[依赖注入系统](Dependency-Injection.md)解析服务,可以使用 `ValidationContext` 对象. -例: +例: ````csharp var myService = validationContext.GetRequiredService(); diff --git a/docs/zh-Hans/Virtual-File-System.md b/docs/zh-Hans/Virtual-File-System.md index 97cf22c73e..8e94542bfd 100644 --- a/docs/zh-Hans/Virtual-File-System.md +++ b/docs/zh-Hans/Virtual-File-System.md @@ -35,7 +35,7 @@ namespace MyCompany.MyProject ![build-action-embedded-resource-sample](images/build-action-embedded-resource-sample.png) -如果需要添加多个文件, 这样做会很乏味. 作为选择, 你可以直接编辑 **.csproj** 文件: +如果需要添加多个文件, 这样做会很乏味. 作为选择, 你可以直接编辑 **.csproj** 文件: ````C# From f34ccb8261ffdcd345334753cc7e3971b2af8325 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Wed, 22 Apr 2020 16:17:12 +0300 Subject: [PATCH 12/65] docs: add Toaster-Service.md --- docs/en/UI/Angular/Confirmation-Service.md | 5 +- docs/en/UI/Angular/Permission-Management.md | 2 +- docs/en/UI/Angular/Toaster-Service.md | 157 ++++++++++++++++++++ docs/en/UI/Angular/images/toast.png | Bin 0 -> 20291 bytes docs/en/docs-nav.json | 8 + 5 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 docs/en/UI/Angular/Toaster-Service.md create mode 100644 docs/en/UI/Angular/images/toast.png diff --git a/docs/en/UI/Angular/Confirmation-Service.md b/docs/en/UI/Angular/Confirmation-Service.md index 56e8f1ce35..d42c323227 100644 --- a/docs/en/UI/Angular/Confirmation-Service.md +++ b/docs/en/UI/Angular/Confirmation-Service.md @@ -1,4 +1,4 @@ -# ConfirmationService +# Confirmation Popup You can use the `ConfirmationService` in @abp/ng.theme.shared package to display a confirmation popup by placing at the root level in your project. @@ -160,5 +160,4 @@ clear( ## What's Next? -- ToasterService - \ No newline at end of file +- [Toast Overlay](./Toaster-Service.md) \ No newline at end of file diff --git a/docs/en/UI/Angular/Permission-Management.md b/docs/en/UI/Angular/Permission-Management.md index ababd25e7f..d86e8c96b2 100644 --- a/docs/en/UI/Angular/Permission-Management.md +++ b/docs/en/UI/Angular/Permission-Management.md @@ -76,4 +76,4 @@ Granted Policies are stored in the `auth` property of `ConfigState`. ## What's Next? -* [Config State](./Config-State.md) \ No newline at end of file +- [Confirmation Popup](./Confirmation-Service.md) \ No newline at end of file diff --git a/docs/en/UI/Angular/Toaster-Service.md b/docs/en/UI/Angular/Toaster-Service.md new file mode 100644 index 0000000000..669ee3b33b --- /dev/null +++ b/docs/en/UI/Angular/Toaster-Service.md @@ -0,0 +1,157 @@ +# Toast Overlay + +You can use the `ToasterService` in @abp/ng.theme.shared package to display messages in an overlay by placing at the root level in your project. + + +## Getting Started + +You do not have to provide the `ToasterService` at module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components, directives, or services. + + +```js +import { ToasterService } from '@abp/ng.theme.shared'; + +@Component({ + /* class metadata here */ +}) +class DemoComponent { + constructor(private toaster: ToasterService) {} +} +``` + +## Usage + +You can use the `success`, `warn`, `error`, and `info` methods of `ToasterService` to display an overlay. + +### How to Display a Toast Overlay + +```js +this.toast.success('Message', 'Title') +``` + +- The `ToasterService` methods accept three parameters that are `message`, `title`, and `options`. +- `success`, `warn`, `error`, and `info` methods return the id of opened toast overlay. The toast can be removed with this id. + +### How to Display a Toast Overlay With Given Options + +Options can be passed as the third parameter to `success`, `warn`, `error`, and `info` methods: + +```js +import { Toaster, ToasterService } from '@abp/ng.theme.shared'; +//... + +constructor(private toaster: ToasterService) {} + +//... +const options: Partial = { + life: 10000, + sticky: false, + closable: true, + tapToDismiss: true, + messageLocalizationParams: ['Demo', '1'], + titleLocalizationParams: [] + }; + + this.toaster.error('AbpUi::EntityNotFoundErrorMessage', 'AbpUi::Error', options); +``` + +- `life` option is the value in milliseconds that determines the closing time. Default value is `5000` +- `sticky` option is the boolean value. If the value passed `true`, toast overlay keep on the screen by ignoring the life option. Default value is `false` +- `closable` option is the boolean value that displays the close icon over the toast overlay or not. Default value is `true`. +- `tapToDismiss` option is the boolean value that allows closing the toast overlay by clicking over. Default value is `false`. +- `yesText` is the text of the confirm button. A localization key or localization object can be passed. Default value is `AbpUi::Yes` +- `messageLocalizationParams` is the interpolation parameters of the message localization. +- `titleLocalizationParams` is the interpolation parameters of the title localization. + +With the above options, the toast overlay looks like this: + +![toast](./images/toast.png) + +### How to Remove a Toast Overlay + +The open toast overlay can be removed manually via the `remove` method by passing the `id` of toast: + +```js +const toastId = this.toast.success('Message', 'Title') + +this.toast.remove(toastId); +``` + +### How to Remove All Toasts + +The all open toasts can be removed manually via the `clear` method: + +```js +this.toast.clear(); +``` + +## API + +### success + +```js +success( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): number +``` + +- `Config` namespace can be imported from `@abp/ng.core`. +- `Toaster` namespace can be imported from `@abp/ng.theme.shared`. + +> See the [`Config.LocalizationParam` type](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/core/src/lib/models/config.ts#L46) and [`Toaster` namespace](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/theme-shared/src/lib/models/toaster.ts) + + +### warn + +```js +warn( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): number +``` + +### error + +```js +error( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): number +``` + +### info + +```js +info( + message: Config.LocalizationParam, + title: Config.LocalizationParam, + options?: Partial, +): number +``` + +### remove + +```js +remove(id: number): void +``` + +Removes an open toast by the given id. + +### clear + +```js +clear(): void +``` + +Removes all open toasts. + +## See Also +- [Confirmation Popup](./Confirmation-Service.md) + +## What's Next? + +- [Config State](./Config-State.md) diff --git a/docs/en/UI/Angular/images/toast.png b/docs/en/UI/Angular/images/toast.png new file mode 100644 index 0000000000000000000000000000000000000000..24cdd0fe0ccd88cb679c452d5929042a56f150f8 GIT binary patch literal 20291 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 LZDb|F=GA`yG#y|> literal 0 HcmV?d00001 diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 8b5d41aa59..472f153321 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -337,6 +337,14 @@ "text": "Permission Management", "path": "UI/Angular/Permission-Management.md" }, + { + "text": "Confirmation Popup", + "path": "UI/Angular/Confirmation-Service.md" + }, + { + "text": "Toast Overlay", + "path": "UI/Angular/Toaster-Service.md" + }, { "text": "Config State", "path": "UI/Angular/Config-State.md" From 832789498080ebfe4dbc1d6ec4759539f779e269 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 22 Apr 2020 22:15:06 +0800 Subject: [PATCH 13/65] Translate some of angular documents. --- docs/zh-Hans/UI/Angular/Loading-Strategy.md | 95 +++++++++++++ docs/zh-Hans/UI/Angular/Localization.md | 140 +++++++++++++++++++- 2 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 docs/zh-Hans/UI/Angular/Loading-Strategy.md diff --git a/docs/zh-Hans/UI/Angular/Loading-Strategy.md b/docs/zh-Hans/UI/Angular/Loading-Strategy.md new file mode 100644 index 0000000000..8e1142dd20 --- /dev/null +++ b/docs/zh-Hans/UI/Angular/Loading-Strategy.md @@ -0,0 +1,95 @@ +# LoadingStrategy + +`LoadingStrategy` 是@abp/ng.core包暴露的抽象类. 扩展它的有两种加载策略: `ScriptLoadingStrategy` 和 `StyleLoadingStrategy`. 它们实现相同的方法和属性,这两种策略都可以帮助你定义延迟加载的工作方式. + +## API + +### constructor + +```js +constructor( + public path: string, + protected domStrategy?: DomStrategy, + protected crossOriginStrategy?: CrossOriginStrategy +) +``` + +- `path` 将 `