Angular Context is a library to bind data to deeply nested child components without passing properties through other components or getting blocked by a router outlet.
If you would like to have further information on why you need a library like this, you may find the reasons below. Otherwise, skip to the quickstart or usage section.
Check demo application out for a preview.
You may also find the introductory blog post helpful.
Data-binding and input properties are great. However, working with them has some challenges:
router-outlet
, data-binding is not available and prop-drilling is no longer an option.This library is designed to improve developer experience by fixing all issues above. It provides context through dependency injection system behind-the-scenes and lets your deeply nested dumb components consume this context easily. It is inspired by React Context, but differs in implementation and is 100% tailored for Angular.
Run the following code in your terminal:
yarn add ngx-context
or if you are using npm:
npm install ngx-context
Import NgxContextModule
into your root module like:
import { NgxContextModule } from 'ngx-context';
@NgModule({
imports: [ NgxContextModule ]
})
export class AppModule {}
Simply put a ContextProviderComponent
around the children and refer to property names to provide.
@Component({
selector: 'parent-component',
template: `
<context-provider provide="someProp someOtherProp">
<!--
components consuming the context can be deeply nested
within the components placed here (inside context provider)
and be able to consume someProp and someOtherProp
-->
</context-provider>
`,
})
export class ParentComponent {
someProp: string = 'Test';
someOtherProp: boolean = true;
notProvided: number = 5;
alsoNotProvided: Observable<> = empty();
}
You may consume any provided context in a component by placing a ContextConsumerDirective
on it. This component can either be a direct or a deeply nested child of the context provider.
<!-- child component will be able to consume all provided props -->
<child-component contextConsumer></child-component>
The name of the props to be provided is set by provide
input and it can take string
or Array<string>
values.
<context-provider provide="someProp someOtherProp">
<!-- consumers will consume someProp and someOtherProp -->
</context-provider>
— or —
<context-provider [provide]="['someProp', 'someOtherProp']">
<!-- consumers will consume someProp and someOtherProp -->
</context-provider>
Provided property names can be dynamically set.
<context-provider [provide]="propertiesToProvide">
<!-- consumers will consume properties defined by propertiesToProvide -->
</context-provider>
Provided property names can be mapped.
<context-provider
provide="someProp"
[contextMap]="{someProp: 'someOtherPropName'}"
>
<!-- consumers will consume someOtherPropName -->
</context-provider>
Context consumers or their parents should be wrapped by ContextProviderComponent
in the parent component.
<context-provider provide="someProp someOtherProp">
<some-context-consumer></some-context-consumer>
<some-other-context-consumer></some-other-context-consumer>
<parent-of-context-consumer></parent-of-context-consumer>
<grand-grand-grand-parent-of-context-consumer></grand-grand-grand-parent-of-context-consumer>
</context-provider>
More than one ContextProviderComponent
can be placed in a parent component.
<context-provider provide="someProp someOtherProp">
<some-context-consumer></some-context-consumer>
<parent-of-context-consumer></parent-of-context-consumer>
</context-provider>
<context-provider provide="yetAnotherProp">
<some-other-context-consumer></some-other-context-consumer>
</context-provider>
Router outlets have no effect on context and can be safely used.
<context-provider provide="someProp someOtherProp">
<router-outlet></router-outlet>
</context-provider>
The easiest way to consume a context is to place a ContextConsumerComponent
inside a child component. It will be able to consume context once provided and behave normally when not.
<!--
place this inside the template of the consumer component
consumer will consume any property provided
-->
<context-consumer></context-consumer>
The name of specific props to be consumed can be set by consume
input and it can take string
or Array<string>
values.
<!-- consumer will consume someProp and someOtherProp -->
<context-consumer consume="someProp someOtherProp"></context-consumer>
— or —
<!-- consumer will consume someProp and someOtherProp -->
<context-consumer [consume]="['someProp', 'someOtherProp']"></context-consumer>
Consumed property names can be dynamically set.
<!-- consumer will consume properties defined by propertiesToConsume -->
<context-consumer [consume]="propertiesToConsume"></context-consumer>
Consumed property names can be mapped.
<!-- consumer will consume someOtherPropName -->
<context-consumer [contextMap]="{someProp: 'someOtherPropName'}"></context-consumer>
If a component cannot take ContextConsumerComponent
in (e.g. 3rd-party components), you can use ContextConsumerDirective
on them.
<!-- consumer will consume any property provided -->
<child-component contextConsumer></child-component>
The name of specific props to be consumed can be set by contextConsumer
input and it can take string
or Array<string>
values.
<!-- consumer will consume someProp and someOtherProp -->
<child-component contextConsumer="someProp someOtherProp"></child-component>
— or —
<!-- consumer will consume someProp and someOtherProp -->
<child-component [contextConsumer]="['someProp', 'someOtherProp']"></child-component>
Consumed property names can be dynamically set.
<!-- consumer will consume properties defined by propertiesToConsume -->
<child-component [contextConsumer]="propertiesToConsume"></child-component>
Consumed property names can be mapped.
<!-- consumer will consume someOtherPropName -->
<child-component [contextMap]="{someProp: 'someOtherPropName'}"></child-component>
There are some cases where you will need the context on a higher level and end up putting properties on a middle component's class. For example, in order to make reactive forms work, a ContextConsumerComponent
will most likely be used and the consumed properties will have to be added to the wrapper component. This is usually not the preferred result. After all, we are trying to keep intermediary components as clean as possible. In such a case, you can use ContextDisposerDirective
on an <ng-template>
and make use of template input variables.
<!-- disposer will dispose any property provided under context -->
<ng-template contextDisposer let-context>
<child-component [someProp]="context.someProp"></child-component>
</ng-template>
The name of specific props to be disposed can be set by contextDisposer
input and it can take string
or Array<string>
values.
<!-- disposer will dispose someProp and someOtherProp under context -->
<ng-template contextDisposer="someProp someOtherProp" let-context>
<child-component
[prop1]="context.someProp"
[prop2]="context.someOtherProp"
></child-component>
</ng-template>
— or —
<!-- disposer will dispose someProp and someOtherProp under context -->
<ng-template contextDisposer="['someProp', 'someOtherProp']" let-context>
<child-component
[prop1]="context.someProp"
[prop2]="context.someOtherProp"
></child-component>
</ng-template>
Properties to dispose can be dynamically set.
<!-- disposer will dispose properties defined by propertiesToDispose under context -->
<ng-template [contextDisposer]="propertiesToDispose" let-context>
<child-component
[prop1]="context.someProp"
[prop2]="context.someOtherProp"
></child-component>
</ng-template>
Disposed property names can be individually assigned to template input variables.
<!-- disposer will dispose prop1 and prop2 -->
<ng-template
contextDisposer
let-prop1="someProp"
let-prop2="someOtherProp"
>
<child-component [prop1]="prop1" [prop2]="prop2"></child-component>
</ng-template>
Note: If you are wondering how you can implement reactive forms using Angular Context, please refer to the demo application.
There are several issues which are simply not addressed yet or impossible with currently available tools.
Component to provide context
Component and directive to consume context
Directive to dispose context
Test coverage
Documentation & examples
Permissive license
Inclusive code of conduct
Issue submission templates
Contribution guidelines
CI integrations
Benchmarks
Optimization
1. ngx.var.VARIABLE syntax: ngx.var.VAR_NAME context: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua* 读或者写 Nginx 变量值:
关于 nginx有一套设计良好的源码,以供分析,本文从ngx_module_t结构体来分析nginx源码结构。ngx_module_t是整个nginx的关键,它提供了整个nginx的模块化的基础。因此,看懂ngx_module_t结构体才能开始入门nginx源码阅读。 ngx_module_t结构体介绍 该结构体描述了整个模块的所有信息,为核心模块进行初始化和调用提供了接口,整个结构体的初始化源码
local delay=3 local handle handle = function(param1,param2) if param1 then return end ngx.log(ngx.ERR,"param is " ..param2) ngx.timer.at(delay,handle,"hello timer again") end l
cycle = ngx_init_cycle(&init_cycle); ngx_timezone_update对于Linux系统来说,没做什么 tp = ngx_timeofday();得到ngx_cached_time tp->sec = 0; 秒数清0 再次调用ngx_time_update 在新的slot存入新的time 更新相应的全局变量 log = old_cycle->log;沿用以
ngx_http_flv_module 模块提供了对 flv 视频的伪流支持。编译的时候带上 --with-http_flv_module。 它会根据指定的 start 参数来指定跳过多少字节,并在返回数据前面附上 FLV 头。 location ~ \.flv$ { flv; } curl localhost/index.flv?start=10 该请求的意思是,从视频文件 index.
ngx-contextmenu A context menu built with Angular (10) inspired by ui.bootstrap.contextMenu. Bootstrap classes are included in the markup, but there is no explicit dependency on Bootstrap. Demo Stackb
ngx-weui 是一个使用 Angular 构建的 WeUI 组件。 在线示例以及API文档。
ngx-fastdfs 是 nginx + lua +fastdfs 实现分布式图片实时动态压缩。 install 进入docker目录docker build -t fastdfs:dev . 使用 docker -idt -p 80:80 fastdfs:dev /bin/bash进入容器执行/etc/rc.local 测试 进入容器执行test目录下的./test.sh或者直接执行下面脚本
ngx-markdown ngx-markdown is an Angular library that combines... Marked to parse markdown to HTML Prism.js for language syntax highlight Emoji-Toolkit for emoji support KaTeX for math expression rende
ngx-admin Who uses ngx-admin?| Documentation | Installation Guidelines | Angular templates New! Material theme for ngx-admin Material admin theme is based on the most popular Angular dashboard templat
@sweetalert2/ngx-sweetalert2 Official SweetAlert2 integration for Angular This is not a regular API wrapper for SweetAlert (which already works very well alone), it intends to provide Angular-esque ut