fix: minor improvements

This commit is contained in:
Zhicheng Wang 2017-07-30 17:40:53 +08:00
parent 4a4b009662
commit 1ec5c6a82f
8 changed files with 99 additions and 47 deletions

View File

@ -629,15 +629,19 @@ Of course, you can also write your own directives. Components such as
## 服务
<img src="generated/images/guide/architecture/service.png" alt="服务" class="left">
<img src="generated/images/guide/architecture/service.png" alt="Service" class="left">
_Service_ is a broad category encompassing any value, function, or feature that your application needs.
*服务*是一个广义范畴,包括:值、函数,或应用所需的特性。
Almost anything can be a service.
A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.几乎任何东西都可以是一个服务。
典型的服务是一个类,具有专注的、明确的用途。它应该做一件特定的事情,并把它做好。<br class="clear">
A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.
几乎任何东西都可以是一个服务。
典型的服务是一个类,具有专注的、明确的用途。它应该做一件特定的事情,并把它做好。
<br class="clear">
Examples include:
@ -728,11 +732,13 @@ Angular 帮助我们*遵循*这些原则 —— 它让我们能轻易地把应
## 依赖注入
<img src="generated/images/guide/architecture/dependency-injection.png" alt="服务" class="left">
<img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left">
_Dependency injection_ is a way to supply a new instance of a class
with the fully-formed dependencies it requires. Most dependencies are services.
Angular uses dependency injection to provide new components with the services they need.“依赖注入”是提供类的新实例的一种方式,还负责处理好类所需的全部依赖。大多数依赖都是服务。
Angular uses dependency injection to provide new components with the services they need.
“依赖注入”是提供类的新实例的一种方式,还负责处理好类所需的全部依赖。大多数依赖都是服务。
Angular 使用依赖注入来提供新组件以及组件所需的服务。<br class="clear">
Angular can tell which services a component needs by looking at the types of its constructor parameters.

View File

@ -385,7 +385,7 @@ That brief syntax does a lot:
### Using the Hero class
## 使用 Hero 类
### 使用 Hero 类
After importing the `Hero` class, the `AppComponent.heroes` property can return a _typed_ array
of `Hero` objects:

View File

@ -128,7 +128,12 @@ Though this is not exactly true. Interpolation is a special syntax that Angular
但严格来讲这是不对的。插值表达式是一个特殊的语法Angular 把它转换成了[属性绑定](guide/template-syntax#property-binding)[后面](guide/template-syntax#property-binding-or-interpolation)将会解释这一点。
But first, let's take a closer look at template expressions and statements.
讲解属性绑定之前,先深入了解一下模板表达式和模板语句。<a href="#top-of-page">back to top</a><a href="#top-of-page">回到顶部</a>
讲解属性绑定之前,先深入了解一下模板表达式和模板语句。
<a href="#top-of-page">back to top</a>
<a href="#top-of-page">回到顶部</a>
<hr/>
@ -242,8 +247,13 @@ Template expressions cannot refer to anything in
the global namespace. They can't refer to `window` or `document`. They
can't call `console.log` or `Math.max`. They are restricted to referencing
members of the expression context.
模板表达式不能引用全局命名空间中的任何东西,比如`window`或`document`。它们也不能调用`console.log`或`Math.max`。
它们只能引用表达式上下文中的成员。<a href="#top-of-page">back to top</a><a href="#top-of-page">回到顶部</a>
它们只能引用表达式上下文中的成员。
<a href="#top-of-page">back to top</a>
<a href="#top-of-page">回到顶部</a>
{@a no-side-effects}
@ -471,8 +481,14 @@ A method call or simple property assignment should be the norm.
Now that you have a feel for template expressions and statements,
you're ready to learn about the varieties of data binding syntax beyond interpolation.
现在,对模板表达式和语句有了一点感觉了吧。
除插值表达式外,还有各种各样的数据绑定语法,是学习它们是时候了。<a href="#top-of-page">back to top</a><a href="#top-of-page">回到顶部</a>
除插值表达式外,还有各种各样的数据绑定语法,是学习它们是时候了。
<a href="#top-of-page">back to top</a>
<a href="#top-of-page">回到顶部</a>
<hr/>
@ -1931,8 +1947,13 @@ Template statement side effects are not just OK, but expected.
Deleting the hero updates the model, perhaps triggering other changes
including queries and saves to a remote server.
These changes percolate through the system and are ultimately displayed in this and other views.
删除这个英雄会更新模型,还可能触发其它修改,包括向远端服务器的查询和保存。
这些变更通过系统进行扩散,并最终显示到当前以及其它视图中。<a href="#top-of-page">back to top</a><a href="#top-of-page">回到顶部</a>
这些变更通过系统进行扩散,并最终显示到当前以及其它视图中。
<a href="#top-of-page">back to top</a>
<a href="#top-of-page">回到顶部</a>
<hr/>

View File

@ -1,2 +1,2 @@
<h1 class="no-toc">API List</h1>
<h1 class="no-toc">API 列表</h1>
<aio-api-list></aio-api-list>

View File

@ -4,13 +4,13 @@
[options]="types"
[selected]="type"
[showSymbol]="true"
label="Type:">
label="类型:">
</aio-select>
<aio-select (change)="setStatus($event.option)"
[options]="statuses"
[selected]="status"
label="Status:">
label="状态:">
</aio-select>
<div class="form-search">

View File

@ -42,24 +42,24 @@ export class ApiListComponent implements OnInit {
// API types
types: Option[] = [
{ value: 'all', title: 'All' },
{ value: 'directive', title: 'Directive' },
{ value: 'pipe', title: 'Pipe'},
{ value: 'decorator', title: 'Decorator' },
{ value: 'class', title: 'Class' },
{ value: 'interface', title: 'Interface' },
{ value: 'function', title: 'Function' },
{ value: 'enum', title: 'Enum' },
{ value: 'type-alias', title: 'Type Alias' },
{ value: 'const', title: 'Const'}
{ value: 'all', title: '全部' },
{ value: 'directive', title: '指令' },
{ value: 'pipe', title: '管道'},
{ value: 'decorator', title: '装饰器' },
{ value: 'class', title: '' },
{ value: 'interface', title: '接口' },
{ value: 'function', title: '函数' },
{ value: 'enum', title: '枚举' },
{ value: 'type-alias', title: '类型别名' },
{ value: 'const', title: '常量'}
];
statuses: Option[] = [
{ value: 'all', title: 'All' },
{ value: 'stable', title: 'Stable' },
{ value: 'deprecated', title: 'Deprecated' },
{ value: 'experimental', title: 'Experimental' },
{ value: 'security-risk', title: 'Security Risk' }
{ value: 'all', title: '全部' },
{ value: 'stable', title: '稳定' },
{ value: 'deprecated', title: '弃用' },
{ value: 'experimental', title: '试验' },
{ value: 'security-risk', title: '安全风险' }
];
@ViewChild('filter') queryEl: ElementRef;
@ -167,7 +167,7 @@ export class ApiListComponent implements OnInit {
type: type !== 'all' ? type : undefined
};
this.locationService.setSearch('API Search', params);
this.locationService.setSearch('API 搜索', params);
}
private setSearchCriteria(criteria: SearchCriteria) {

View File

@ -1,7 +1,16 @@
import {
Component, ComponentFactory, ComponentFactoryResolver, ComponentRef,
DoCheck, ElementRef, EventEmitter, Injector, Input, OnDestroy,
Output, ViewEncapsulation, HostListener
Component,
ComponentFactory,
ComponentFactoryResolver,
ComponentRef,
DoCheck,
ElementRef,
EventEmitter,
HostListener,
Injector,
Input,
OnDestroy,
Output,
} from '@angular/core';
import { EmbeddedComponents } from 'app/embedded/embedded.module';
@ -20,7 +29,7 @@ const initialDocViewerContent = initialDocViewerElement ? initialDocViewerElemen
@Component({
selector: 'aio-doc-viewer',
template: ''
template: '',
// TODO(robwormald): shadow DOM and emulated don't work here (?!)
// encapsulation: ViewEncapsulation.Native
})
@ -33,14 +42,12 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
@Output()
docRendered = new EventEmitter();
constructor(
componentFactoryResolver: ComponentFactoryResolver,
elementRef: ElementRef,
embeddedComponents: EmbeddedComponents,
private injector: Injector,
private titleService: Title,
private tocService: TocService
) {
constructor(componentFactoryResolver: ComponentFactoryResolver,
elementRef: ElementRef,
embeddedComponents: EmbeddedComponents,
private injector: Injector,
private titleService: Title,
private tocService: TocService) {
this.hostElement = elementRef.nativeElement;
// Security: the initialDocViewerContent comes from the prerendered DOM and is considered to be secure
this.hostElement.innerHTML = initialDocViewerContent;
@ -49,7 +56,7 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
const factory = componentFactoryResolver.resolveComponentFactory(component);
const selector = factory.selector;
const contentPropertyName = this.selectorToContentPropertyName(selector);
this.embeddedComponentFactories.set(selector, { contentPropertyName, factory });
this.embeddedComponentFactories.set(selector, {contentPropertyName, factory});
}
}
@ -71,16 +78,18 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
// and is considered to be safe
this.hostElement.innerHTML = doc.contents || '';
if (!doc.contents) { return; }
if (!doc.contents) {
return;
}
this.addTitleAndToc(doc.id);
// TODO(i): why can't I use for-of? why doesn't typescript like Map#value() iterators?
this.embeddedComponentFactories.forEach(({ contentPropertyName, factory }, selector) => {
this.embeddedComponentFactories.forEach(({contentPropertyName, factory}, selector) => {
const embeddedComponentElements = this.hostElement.querySelectorAll(selector);
// cast due to https://github.com/Microsoft/TypeScript/issues/4947
for (const element of embeddedComponentElements as any as HTMLElement[]){
for (const element of embeddedComponentElements as any as HTMLElement[]) {
// hack: preserve the current element content because the factory will empty it out
// security: the source of this innerHTML is always authored by the documentation team
// and is considered to be safe
@ -93,7 +102,13 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
private addTitleAndToc(docId: string) {
this.tocService.reset();
let title = '';
const titleEl = this.hostElement.querySelector('h1');
const titleElements = this.hostElement.querySelectorAll('h1');
let titleEl;
if (titleElements.length > 1) {
titleEl = titleElements[1];
} else if (titleElements.length > 0) {
titleEl = titleElements[0];
}
// Only create TOC for docs with an <h1> title
// If you don't want a TOC, add "no-toc" class to <h1>
if (titleEl) {

View File

@ -66,11 +66,21 @@ export class TocService {
private findTocHeadings(docElement: Element): HTMLHeadingElement[] {
const headings = docElement.querySelectorAll('h1,h2,h3');
const skipNoTocHeadings = (heading: HTMLHeadingElement) => !/(?:no-toc|notoc)/i.test(heading.className);
const skipNoTocHeadings = (heading: HTMLHeadingElement) => !/(?:no-toc|notoc)/i.test(heading.className) && !this.isOriginalText(heading);
return Array.prototype.filter.call(headings, skipNoTocHeadings);
}
private isOriginalText(heading: HTMLHeadingElement): boolean {
if (heading.hasAttribute('translation-origin')) {
const prevNode = heading.previousElementSibling;
if (prevNode.hasAttribute('translation-result')) {
return true;
}
}
return false;
}
private resetScrollSpyInfo() {
if (this.scrollSpyInfo) {
this.scrollSpyInfo.unspy();