当前位置: 首页 > Web前端 > JavaScript

Angular-使用@component装饰器属性

时间:2023-03-26 20:11:13 JavaScript

带有@Component()装饰器的TypeScript类是Angular组件中非常重要的一部分。常用的属性包括以下选择器:CSS选择器,用于定义如何使用模板使用组件模板或templateUrl:HTML模板样式或styleUrls:一组可选的CSS样式和一些不太常用的属性,我们来看看他们。如何使用changeDetection:@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],changeDetection:ChangeDetectionStrategy.OnPush})changeDetection用于定义当前组件的变更检测策略。当组件被实例化时,Angular会创建一个变化检测器,它负责传播组件每个绑定值的变化。它在源码中的值是:changeDetection?:ChangeDetectionStrategy,我们来看看ChangeDetectionStrategy在源码中是怎么定义的。exportdeclareenumChangeDetectionStrategy{OnPush=0,Default=1}Default:变更策略为CheckAlways,默认值。对此无话可说。它总是被检测到。即使组件中的属性和@Input属性没有变化,OnPush也会不断检测到变化:变化策略是CheckOnce(按需)。使用ChangeDetectionStrategy.OnPush也是一种优化性能的方法。毕竟是按需检测,不会一直检测,但是使用也是有严格条件的,不然一不小心就会出现bug。如果业务满足以下条件,可以放心使用:组件的视图变化只依赖于@Input属性的变化。如果有一个依赖于组件本身的属性,当@Input属性是非对象时不能使用它,或者当它是对象时每个@Input属性都不能使用。更改是更改对象本身的方式(例如:obj=xxx),而不是更改引用的方式(例如:obj.propertyName=xxx)。如果@Input属性的变化是为了改变引用方法,或者你想触发视图检测变化,你也可以使用ChangeDetectorRef来手动触发变化。注意:Angular每次做变更检测时,组件树都是从上到下的。如果父组件设置为OnPush,就会按照这个策略检测父组件和它的子组件。此时子组件即使设置为Default也是无效的。并且因为父组件是OnPush,所以即使传递给子组件的属性发生变化,也不会更新到子组件(因为视图不会重新渲染)。使用时必须慎重考虑。哈哈,感觉说多了,changeDetection可以单独写一篇文章,如果大家需要了解,我会单独开一篇文章。嗯,下一篇~viewProviders中提到需要了解依赖注入,但是关于DI要学的东西很多,值得单独说明。本章的重点不是DI,就不多说了。源码中viewProviders的取值是:viewProviders?:Provider[];意思是定义一组只在view中可用的Provider对象注意:前提是对象没有注入到根模块,或者组件所在的模块,否则定义viewProviders是没有意义的,as下面我们有一个ServiceDemoservice@Injectable()//注意这里不能加{providedIn:'root'},否则会被注入到根模块中,exportclassServiceDemo{...}可以到处使用。我们把ServiceDemo加入到ChildComponent组件的viewProviders中,ServiceDemo既没有注入到根模块,也没有注入到ChildComponent所在的模块@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],viewProviders:[ServiceDemo]})exportclassChildComponentimplementsOnInit{...}我们只能在ChildComponent的视图中使用ServiceDemo的属性或方法,如果在组件,将报错。供应商与上述有关。如果我们想在ChildComponent的视图和组件中使用ServiceDemo的属性或方法,或者只在组件中使用它们,我们应该将它们添加到提供者中,如下:@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],providers:[ServiceDemo]})exportclassChildComponentimplementsOnInit{...}使用viewProviders或providers,目的仅将提供者对象注入到某个组件或组件视图中。这样的provider对象必须是小范围使用的封装对象,以免注入根模块影响首屏加载。encapsulation用于定义Component的模板和样式封装选项。源码中encapsulation的值是encapsulation?:ViewEncapsulation,我们看看ViewEncapsulation是怎么定义的。exportdeclareenumViewEncapsulation{Emulated=0,//DefaultNative=1,//ObsoleteNone=2,ShadowDom=3}Emulated:这是默认选项。它会在Host元素上添加_nghost-xxx-xxx,在非Host元素上添加_ngcontent-xxx-xxx属性来模拟原生选择器,用于替换class和id,使样式isolatedcomponent不影响外部,组件内部定义的样式只作用于这个组件。父组件父组件有效!

childworks

None:不提供模板或样式封装,即该组件中的样式将被添加到全局,应用于整个文档。ShadowDom:封装原生的ShadowDOM特性,为组件的Host元素创建一个ShadowRoot。组件样式不会受到全局样式的影响,组件中定义的样式范围仅限于ShadowDOM。使用ShadowDom组件的子组件也会应用组件样式,因为子组件也在ShadowRoot中,ShadowDom可以应用微前端样式隔离。插值覆盖默认插值表达式开始和停止定界符({{和}})。它的值定义为插值?:[string,string]@Component({selector:'app-parent',templateUrl:'./parent.component.html',styleUrls:['./parent.component.scss'],interpolation:['(',')']})如果你不喜欢使用{{value}}这样的插值方式,可以改成你喜欢的方式eg:(value)preserveWhitespaces它的值为Boolean,默认为false,从编译的模板中删除可能多余的空白字符。空白字符是那些与JavaScript正则表达式中的\s匹配的字符。真实保存。entryComponents应与当前组件一起编译的组件集合。对于此处列出的每个组件,Angular将创建一个ComponentFactory并将其保存到ComponentFactoryResolver中。官方解释,你看过还是不知道是什么?跟我一起看看。假设您在项目中定义了一些组件。这些组件编译工具无法识别它们在项目中的使用。TreeShaking工具将从最终的代码包中提取这些组件。但实际上,这些组件可能是路由组件,也可能是动态加载的。它们必须显式添加到entryComponents。@NgModule的entryComponents中需要添加路由组件。动态加载的组件取决于它们的使用范围。如果只在一个或两个组件中使用,可以将它们添加到组件的entryComponents中。动画用于引入定义动画的触发器。它们需要与@angular/animations结合使用。本章将不着重讲解moduleId包含该组件的模块ID。它可以在使用CommonJS作为模块化工具时使用。Angular使用es6模块化语法。估计这个属性不会用于日常开发。下面是继承自@Directive的属性inputs,列出一组可用于数据绑定的input属性,类似于@Input。Angular会在变更检测期间自动更新输入属性。使用方法如下:@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],inputs:['name','id:child-id']})exportclassChildComponentimplementsOnInit{name:string;身份证号;//指的是child-id的值}使用输入时,编辑器也会提示使用@Input而不是输入元数据属性。貌似官方不推荐输入。使用@Input可以定义private或者shared,还可以定义数据类型。实在找不到input存在的意义。哈哈~~可能不用介绍@Input,看@Component装饰器的配置就知道input属性是它的优势,也可能还有其他优势,但我技术有限,还没有还没找到哈哈~~~outputs和inputs类似,功能和@Output一样,用法如下:@Component({selector:'app-child',outputs:['bankNameChange']template:``})classChildDir{bankNameChange:EventEmitter=newEventEmitter();}exportAs定义了一个名称,用于将指令分配给模板中的变量组件。虽然它继承了Directive的属性,但是我觉得这个属性在Component中并没有起到什么特殊的作用。它在指令中仍然有用。假设我们定义了一个child-dir指令@Directive({selector:'child-dir',exportAs:'child'})classChildDir{}现在我们在模板中使用它
在组件中获取它们@ViewChild('c')child;@ViewChild('c1')child1;打印出来发现c是child-dir指令的一个实例,c1是ElementRef的一个实例。这个时候,好像还是不太明白它的具体用途。ElementRef实例可用于操作DOM,其属性和方法可通过获取child-dir实例来访问。下面是Angular内置指令NgModel的一个例子。NgModel指令还使用exportAs值作为ngModel//inthetemplateThisfieldisrequired

//在组件@ViewChild('textModel')textModel:NgModel;/**你现在可以访问this.textModel.hasError('required')this.textModel.validthis.textModel.disabled**/是不是很方便,我们不用newFormGroup或者FormControl就可以访问到我们想要的属性和方法,上面只适合简单的表单验证,它建议使用newFormGroup创建一个Form对象来处理表单,使代码更具可读性。查询配置一些将被注入到该指令中的查询。作用与@ViewChildren、@ContentChildren、@ViewChild、@ContentChild类似host使用一组键值对将类的属性映射到宿主元素的绑定(Property、Attribute和events).@Component({selector:'app-child',templateUrl:'./child.component.html',host:{'name':'app-child','onclick':'returnfalse'//表示调用DOM事件的preventDefault函数,该语句可以引用局部变量event获取事件数据}})//渲染结果jit如果存在,该指令/组件将被AOT编译器忽略。它留在发布代码中,JIT编译器尝试在运行时在浏览器中编译它。为确保其行为正确,应用程序必须导入@angular/compiler。喜欢就点个赞吧~~~