html,css,javascript, typescript, angular

使用visibility隐藏元素时,元素及其内容应该出现的位置会留下一片空白区域,仍然会在文档流中占据位置。

display: none;完全从文档中拿出。

设置元素width值,并且将左右外边距都设为auto,导致元素居中。

内边距不能继承,外边距不继承,边框不继承,float属性不继承,定位不继承,z-index不继承,overflow不继承。

边框的默认颜色是元素的color属性的值。

如果一个元素位于另一个元素的上面,对于相互接触的两个margin(即元素相互接触的下外边距和上外边距),仅使用其中较大的一个,另一个外边距会被叠加。左右外边距不叠加。

当em值用于内边距和外边距时,它的值是相对于元素的字体大小的,而不是相对于父元素的字体大小的。

浮动的元素并不会影响父元素或者其它祖先元素的高度,因此从这一点来说,它不属于文档流的一部分。

对某个元素使用clear属性,该元素和它后面的元素就会显示在浮动元素的下面。

让浮动的父元素自清除:

添加clearfix类,并添加css片段:

 

.clearfix:after {
  content:".";
  display:block;
  height:0;
  visibility:hidden;
  clear:both;
}

应该将clear属性添加到不希望环绕浮动对象的元素上。因此,如果要让一个元素在右侧没有浮动元素之后才显示,就为它添加clear:right;。而clearfix和overflow方法是应用于浮动元素的父元素或祖先元素的。

对父元素添加overflow:hidden会强制它包围浮动元素。

背景有8个属性构成:

 

background:
  url(sweettexture.jpg)     /*image*/
  top center / 200px 200px  /*position*/
  no-repeat                 /*repeat*/
  fixed                     /*attachment
  padding-box               /*origin*/
  content-box               /*clip*/
  red;                      /*color*/


对绝对定位元素的父元素(非body)设置position:relative,从而让绝对元素可以相对其父元素(而不是body元素)进行绝对定位,这样就可以让绝对元素显示在我们希望它显示的位置。

 

 

 

绝对定位和固定定位都是完全移出文档流。固定定位元素的定位上下文是视口,因此它不会随页面滚动而移动。

注意:固定定位在很多移动浏览器中效果不佳。

定位的默认设置是static。

z-index只对相对,绝对,固定定位有影响,而对static定位没有影响,static元素总是在最底层。

vertical-align只能用于表格和行内元素,不能用于块级元素。

只有HTML中不包含width和height属性,图像才有可能变成可伸缩的图像。可伸缩图像可以根据包含它们的元素的尺寸按比例缩放。但是不会比其本来的宽度更宽。使用css控制缩放,一定要使用max-width:100%而不是width:100%;。

使用background-size属性对背景图像进行缩放,这个属性是最有用,最复杂的背景属性之一,有四种不同的语法:

1. 关键字,auto(浏览器自动计算图像大小和宽高比),cover(图像覆盖背景),contain(必须显示这个图像,哪些边上有空白)。

2. 一个值,如background-size: 400px;这个指宽度,高度被置为auto。

3. 二个值,宽和高

5. 多个图像,混合上面多种方法:

 

html {
  background: url(greatimage.jpg), url(wonderfulimage.jpg);
  background-size: 300px 100px, cover;
  /* 第一个图像 300x100, 第二个图像覆盖整个区域 */
}

浏览器的默认字体大小是16px。
 

图来自:https://segmentfault.com/a/1190000003038583

bootstrap的屏幕规格:

xs: extra small,特别小,小于576px

sm: small, 小,576px以及以上

md: 中等,768px以及以上

lg: large, 大,992px以及以上

xl: extra large, 特别大,1200px以及以上

angular5对于父元素和子元素的双向绑定定义了语法糖:

 

<app-sizer [(size)]="fontSizePx"></app-sizer>

等价于:

 

 

<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>

模板引用变量(template reference variable)的作用于(scope)是整个的template;而模板输入变量是component的属性。模板引用变量前面的#可以用ref-代替,如下:

 

<input ref-fax placeholder="fax number">
<button (click)="callFax(fax.value)">Fax</button>

所有的components都是directives。

 

父component和子component之间可以通过服务进行通讯,服务类可以使用rxjs库的Observable和Subject类。

其中每一个Subject都是一个Observable(可观察对象),可以订阅,同时,每一个Subject也可以作为Observer(观察者),Subject同样也是一个由next(v),error(e)和complete()这些方法组成的对象。调用next(theValue)方法后,Subject会向所有已经在其上注册的Observer多路推送theValue。

angular2文档的Component Interaction最后一节的例子讲了一个向宇航员宣布任务,宇航员确认的例子:

父有个按钮“宣布”任务,
下面有三个宇航员,每个宇航员
父的构造函数订阅了服务的missionConfirmed$这个Observable

每个宇航员的component构造函数订阅了服务的missionAnnounced$这个Observable

服务有两个方法:
announceMission
confirmMission

这两个方法对Subject进行操作

点击“宣布”按钮,调用服务的announcedMission方法,把第一个任务“飞向月球”推送到每个宇航员。
router在每个模板内部只能支持一个主要的匿名outlet。

ActivatedRoute接口定义如下:

ActivatedRoute可以用来查询路由参数如/hero/:id, hero/11, 这个11能被查询到,这样就不用input参数

往component里面赋值了,全部由router来搞定。

路由特定的参数(route-specific parameters),又叫做矩阵参数(matrix parameters):

/inbox;a=v1/33;b1=v1;b2=v2

{path:'inbox', params: {a: 'v1'}}

{path:'33', params: {b1:'v1',b2:'v2'}}

导航分为命令式和声明式(imperatively navigation and declar)

默认情况下,在导航过程中路由器会重置查询参数(query params),如果想在导航过程中保持

查询参数不变,请参照下例:

router.navigate('/inbox/33/message/44',
{preserveQueryParams: true, preserveFragment: true})

RouterModule.forRoot 新建一个模块,这个模块包含所有的路由器指令,所有给定的路由,以及路由器服务本身;RouterModule.forChild 新建一个模块,这个模块包含所有的路由器指令,所有给定的路由,但是不包含路由器服务。

form,每个input元素有一个name元素,这是angular用来把这个form control注册到form里面去的。

imports, declarations, exports区别:

1. imports: 把别的module包含进来,这样本身module的component模板就能使用别的module里面的comonents,directives和pipe了;这些别的components,derectives和pipe还必须在别的module里面exports才行。

A模块imports B模块,那么B模块里面的components,directives和pipes都能被A模块里面的代码使用了,比如B模块里面有吧b1和b2两个components,那么b1和b2必须exports出来才能被A使用。

2. 微语法(microsyntax), 模板输入变量(template input variable), 结构性指令(structural directives)

结构性指令后面双引号括起来的部分叫做microsyntax.

3. 属性指令(attribute directive), 同一个html元素可以应用多个属性指令,但是结构性指令一个html元素只有一个。

4. *ngIf,不是隐藏,而是从DOM中去掉html元素。

5. 结构性指令前面的星号(*)是语法糖,会扩展为<ng-template>

6. *ngFor复杂的例子:

 

<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
  ({{i}}) {{hero.name}}
</div>

7. 上例中hero, i, odd都是模板输入变量, 该变量用let来申明。

 

8. 模板引用变量(template reference variable)

9. ngIf和ngFor不能应用于同一个html元素上。
10. <ng-container>,如果使用结构性指令,但找不到宿主元素,可采用<ng-container>

11. *ngIf后面的字符串为模板表达式

12. interpolation{{}}绑定属性,angular会自动从component中抽取值显示,在任何异步事件发生之后(键盘,定时器,http响应)自动刷新显示。

{{}}之间可以写那些东西?只要是模板表达式就行,那么模板表达式能写什么东西呢?很多,例如:

a. 数学表达式, 1+1, 2*3, 但是=,+=,-=, new, ;,位运算符都不行

b. 组件自身的属性

c. 模板上下文(不是表达式上下文)之一的模板输入变量<div *ngFor="let hero of heroes">{{hero.name}}</div>

d. 模板上下文(不是表达式上下文)之一的模板引用变量<input #heroInput>{{heroInput.value}}

e. 布尔求反!是可以的

f. 组件自身的方法调用

13. 事件绑定

类似(Click)="template statements", 模板语句基本和模板表达式一样,但是人家支持=和链表达式(;和,)。

 

13. 模板绑定和properties以及events相关,和attributes无关,html的attribute是用来初始化DOM的properties的,初始化完了,就和它没有关系了。

14. 绑定的target是DOM里面的东西,target可以是(DOM 元素| component| directive)属性,(DOM 元素| component| directive)事件,偶然情况下也绑定到一个attribute名称。

15. 模板表达式和模板语句一样,只能引用上下文中的方法和变量,而不能引用全局的变量和方法如window等。

16. 父子component之间的交流可通过property binding:

 

<app-hero-detail [hero]="currentHero"></app-hero-detail>

上述这种情况其实可以通过路由器来解决。

 

17. property 绑定是单向的,而且是set的,无法读取目标元素的值,如果要读取,使用ViewChild和ContentChild。也不能在目标元素上调用方法。

18. 属性绑定也可以加前缀bind-代替中括号:

 

<img bind-src="heroImageUrl">

19. 目标名称一般来说是元素property,但是Angular会先看是不是directive的property。属性绑定后面的双引号里面的是模板表达式:template expression.

 

20. property binding的中括号会要求angular评估表达式的值,如果不带中括号,双引号里面内容会当做字符串。
21. attribute binding,有时目标元素只有attribute,没有property,只能用attribute binding,语法是[attr.xxx]="yyy"

22. 父组建加载子组件,通过OnChanges接口监控任何输入属性的变化(input properties)。

23. 动态组件,在一个html中写一个组件模板,但是模板的类型不是固定的,就要用到动态组件,类似多态。

24. 如果父亲组件想调用子组件的方法,可通过模板引用变量:

 

  <button (click)="timer.start()">Start</button>
  <button (click)="timer.stop()">Stop</button>
  <div class="seconds">{{timer.seconds}}</div>
  <app-countdown-timer #timer></app-countdown-timer>

 

25. 限制provider作用范围的二种方法,一是lazy load,一是组件级别的providers数组。

 

26. 如果一个module里面的某个组件的template需要在另外一个module里面使用,需要在该module的exprots数组里面exports该组件。

27. provider告诉injector如何创建service,没有provider,injector不知道自己要负责注入该service,也不能够创建service。

28. 两个component的template互相嵌套,里面的驻留在<ng-content>槽子里面,如下所示:

<app-hero-bio [heroId="1"><app-hero-contact></app-hero-contact></app-hero-bio>

 

其中外层的template如下所示:

template: `
  <h4>{{hero.name}}</h4>
  <ng-content></ng-content>
  <textarea cols="25" [(ngModel)]="hero.description"></textarea>`,
 

29. @Optional修饰,告诉angular,如果找不到依赖项,请继续,不会抛出异常

30. @Host修饰,停止向host组件以外的组件去向上朝赵依赖。具体参看DI in Action

31. 想访问directive修饰的DOM元素,用ElementRef,这是DOM元素的包装器。

31. provider就是发布服务的菜谱, provider is a recipe for delivering a service associated with a token.

32. 如果依赖是primitive类型的,而且必须是inject进来的,而不是构造函数传递进来的,就要用@Inject修饰一下,如下:

@Component({
  selector: 'app-hero-of-the-month',
  templateUrl: './hero-of-the-month.component.html',
  providers: [
    { provide: Hero,          useValue:    someHero },
    { provide: TITLE,         useValue:   'Hero of the Month' },
    { provide: HeroService,   useClass:    HeroService },
    { provide: LoggerService, useClass:    DateLoggerService },
    { provide: MinimalLogger, useExisting: LoggerService },
    { provide: RUNNERS_UP,    useFactory:  runnersUpFactory(2), deps: [Hero, HeroService] }
  ]
})
export class HeroOfTheMonthComponent {
  logs: string[] = [];

  constructor(
      logger: MinimalLogger,
      public heroOfTheMonth: Hero,
      @Inject(RUNNERS_UP) public runnersUp: string,
      @Inject(TITLE) public title: string)
  {
    this.logs = logger.logs;
    logger.logInfo('starting up');
  }
}

33. 类-接口, class-interface,只用在依赖注入,抽象类MinimalLogger,如下:

{ provide: MinimalLogger, useExisting: LoggerService },

类接口主要用于缩小一个庞大的api到几个方法。

34. 注入令牌,InjectionToken,是指不是类对象的依赖对象,可以是简单的,如:日期,数字,字符串,或者函数,数组。

35. 获取一个组件的引用是比较棘手的。虽然应用是一颗组件树,但是并没有api可以访问这棵树。访问child引用还是有api的,但是对于parent引用,需要用到injector,因为每个组件实例都要加到injector的container中去,用DI访问父组件。

35. 如果在有组件继承的情况下要访问父组件引用,需要用类-接口,并且父组件要定义一个别名provider,参见DI in Action

36. unidirectional data flow意思是数据绑定是从父到子的,事件是从子到父的。参看:

https://stackoverflow.com/questions/39708018/angular2-unidirectional-data-flow

37. 在组件级别注册一个provider,每一个新的组件实例都会获得一个新的服务实例,而在root module级别,在所有的组件得到的服务实例是同一个。

38. 用router在不同的Component之间导航,selector就没有存在的必要了。

keyword: access, share

多态的一个例子参见DI in Action

 

C# HttpWebRequest发送post request到spring boot:

 

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string json = "{\"username\":\"james\"," +
                  "\"password\":\"james\"}";

    streamWriter.Write(json);
    streamWriter.Flush();
    streamWriter.Close();
}

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

Content-Type实体头application/json和application/x-www-form-urlencoded区别:

第一种情况告诉web server,发送的数据格式为:

{ Name: 'John Smith', Age: 43 }

第二种告诉web server,发送的数据直接放在url中,格式为:

Name=John+Smith&Age=43

如果请求使用了application/x-www-form-urlencoded,在spring boot的controller端对传上来的参数不能使用@RequestBody

来修饰,否则会出现错误。

"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported"

或者在Map参数前面加上@RequestParam修饰:

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam Map<String, String> body ) {
  //work with Map
}

请求放的http报头结构:通用报头|请求报头|实体报头

响应方的http报头结构:通用报头|响应报头|实体报头

Accept代表发送端(客户端)希望接受的数据类型。

比如:application/json;charset=utf-8,代表客户端希望接受的数据类型是json类型。

用fiddler来监控.net程序发出的http请求包以及响应包:

fiddler启动之后作为默认的代理127.0.0.1:8888, 所有的本地包都会走这个代理,但是.net程序有个例外,就是看到发送到本机的http请求,就会绕过代理,所以请把host改为"ipv4.fiddler",fiddler看到这个host,会自动把host改为127.0.0.1

另外在c#代码里面,添加:

GlobalProxySelection.Select = new WebProxy("127.0.0.1", 8888);

这样,如果web server和fiddler运行在同一台机器上,所有的http请求都可以看到了,开森!!

注意:fiddler在这种情况下不能设置filter。

在Typescript里面使用第三方javascript库:

方法一:

1. 先安装js库, npm install --save underscore

2. http://microsoft.github.io/TypeSearch搜索类型文件,这里输入underscore,得到@types/underscore

3. 安装类型文件 npm install --save @types/underscore

4. import到angular4项目里面, import * as _ from 'underscore';

5. 使用:

...
import * as _ from 'underscore';
...
export class AppComponent {
  constructor() {
    const myArray: number[] = [9, 1, 5];
    const lastItem: number = _.last(myArray); //Using underscore
    console.log(lastItem); //5
  }
}

方法二:

如果没有d.ts类型文件,

1. 在angular项目的typings.d.ts文件底部加上 declare module 'underscore';

2. 和方法一的4,5步一样。

方法三:

如果不想自己创建.d.ts文件,也不想申明模块,

1. 可以从网上下载js文件,放到src/assets目录下,这个目录会编译到build/assets目录里面,然后在index.html文件中:<script src="assets/jssha.js"></script>

2. 然后在要用jsSHA的地方先申明一下:

declare var jsSHA: any;

下面就可以用了。

方法四:

有的js库自身已经包含index.d.ts文件或者类似文件,这是只要npm install --save xlsx;

然后在需要用的ts文件中:

import * as XLSX from 'xlsx';

即可。

 

Function的bind()方法,这个方法会创建一个函数的实例,其this值会被绑定到传给bind函数的值。不像apply和call,这两个函数每次调用都需要传递作用阈对象进去(this指针)。

 

window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue

 

类型定义文件(*.d.ts)

 

很多主流的库都是javascript写的,但是javascript不支持类型,为了让javascript库支持类型,以便在typescript环境中使用,需要类型定义文件(*.d.ts)。

 

比如在一个javascript文件中定义了一个变量和一个函数:

 

var temp = "hello!";
function foo(name) {
  return name.substr(0, 3);
}

需要先定义一个类似于c++头文件的类型定义文件.d.ts

 

// file: sample01.d.ts

declare let temp: string;

declare let test: (name: string) => string;

在TypeScript文件中通过三斜线指令引用该文件

// file: sample02.ts

/// <reference path="./sample01.d.ts">

console.log(temp);

console.log(foo("world"));
 

switchMap类似于 mergeMap,但是当源 Observable 发出值时会取消内部 Observable 先前的所有订阅

angular2中的不同对象之间的交流:

1. 父组件访问子组件,完全通过template,在class里面没有交流:

这个方法叫做局部变量,通过local variable引用子组件:

  <h3>Countdown to Liftoff (via local variable)</h3>
  <button (click)="timer.start()">Start</button>
  <button (click)="timer.stop()">Stop</button>
  <div class="seconds">{{timer.seconds}}</div>
  <app-countdown-timer #timer></app-countdown-timer>

2. 父组件访问子组件,完全通过ts代码,在类里面引用,不通过template:

这个方法需要@ViewChild和AfterViewInit接口的支持:

timer就是局部变量inject子组件,赋给一个成员变量,要用@ViewChild修饰:

@ViewChild(CountdownTimerComponent)
  private timerComponent: CountdownTimerComponent;

3. 子组件通过按钮事件和父组件通信

子组件的template上有个按钮,点击按钮,告诉EventEmitter发出一个事件。父组件绑定到子组件的事件:

子组件template:

template: `
<div>
  <img src="{{heroImageUrl}}">
  <span [style.text-decoration]="lineThrough">
    {{prefix}} {{hero?.name}}
  </span>
  <button (click)="delete()">Delete</button>
</div>`

子组件代码:

// This component makes a request but it can't actually delete a hero.
deleteRequest = new EventEmitter<Hero>();
delete() {
  this.deleteRequest.emit(this.hero);
}

父组件的template:

<app-hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></app-hero-detail>

要点:deleteRequest是子组件的属性,deleteHero是父组件的函数

 

有时候打开git gui会有很多明明是一样的文件,确被报告为不一样的,有很多警告,可以关掉:

git config core.autocrlf true

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

novodexx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值