I have an Angular 1 app that works with a simple contentEditable
directive, which can be used like this in templates:
<span contenteditable="true" ng-model="model.property" placeholder="Something">
Editing the element would fire $setViewValue(element.html()
and it worked as expected.
I would like to make something in Angular2 with a similarly succinct template syntax. Ideally, I would like the template to look like this:
<span contentEditable="true" [(myProperty)]="name"></span>
where 'name' is a property on the component and have the directive update the component when changed. I feel like I'm close with this (Plunker Link):
//our root app component
import {Component, Input, Output Directive, ElementRef, Renderer, OnInit} from 'angular2/core'
@Directive({
selector: '[contentEditable]',
host: {
'(blur)': 'update($event)'
}
})
export class contentEditableDirective implements OnInit {
@Input() myProperty;
constructor(private el: ElementRef, private renderer: Renderer){}
update(event){
this.myProperty = this.el.nativeElement.innerText;
}
ngOnInit(){
this.el.nativeElement.innerText = this.myProperty;
}
}
This idea works if I pass an object like {name: "someName"}
but if just pass a property it seems like it's passing the value, but not the reference and so the binding doesn't flow back to the component. Is there a way to do this that will still allow a template syntax that isn't verbose but still allows easy reuse of the directive.
A component is a single unit that encapsulates both view and logic whereas directives are used to enhance the behavior of components or dom elements and it doesn't have any templates. Component extends directive so every component is a directive.
The Component is used to break up the application into smaller components. That is why components are widely used in later versions of Angular to make things easy and build a total component-based model. The Directive is used to design reusable components, which are more behavior-oriented.
This should be a component, and here's how it use: @Component({ selector: 'nb-menu', styleUrls: ['./menu. component. scss'], template: ` <ul class="menu-items"> <ng-container *ngFor="let item of items"> <li nbMenuItem *ngIf="!
replace: true means that the content of the directive template will replace the element that the directive is declared on, in this case the <div myd1> tag.
If you simply want to change the value using pure JavaScript and do not want to go towards the [(model]) route, then this is for you.
const input = this.el.nativeElement.querySelector('#myElement');
input.value = 'My Programmatic Value';
input.dispatchEvent(new Event('input'));
Issue - https://github.com/text-mask/text-mask/issues/696
Solution - https://github.com/text-mask/text-mask/issues/696#issuecomment-354887412
Hope this helps someone.
Cheers!
I found this very smooth solution that worked for my case (adding a readonly role to existing UI) using the @Host decorator for injecting the component you want to set property of in the Directive. In my case I have an abstract class with readonly property that is then extended by all custom components.
@Directive({
selector: 'authCheck'
})
export class ComponentReadonlyDirective implements OnInit {
constructor(private authService: AuthorizationService,
@Host() private baseComponent: BaseComponent) {
}
ngOnInit() {
if (!this.authorizationService.canEdit()) {
this.baseComponent.readonly = true;
}
}
}
Where in the selector part I put directly the selectors of my custom components that implement the BaseComponent (e.g. my-comp). This is because I want the directive to be automatically applied to all instances of my-comp. I have an additional param that can turn the directive off.
If this is a single component to use the directive - put it on the place of BaseComponent.
If multiple components will use the same directive - you'll need to specify what will be injected on the @Host parameter by specifying a provider in the extending class:
@Component({
selector: 'my-comp',
...
providers: [{
provide: BaseComponent, useExisting: forwardRef(() => MyComp)
}]
})
export class MyComp extends BaseComponent { ... }
Source: https://github.com/angular/angular/issues/13776
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With