Let's say I have this code
table(my-attr="value")
...complex component Jade...
and I would like render that my-attr base on property delivered into component. Since v-if works on whole element I cannot do something like
table(my-attr="value", v-if="myProp")
table(v-else)
because I would have to duplicate all the code inside table.
How can I achieve that?
You can use v-bind or interpolate the value directly with {{}}
// (sorry, no jade)
<table v-bind:attribute1="someMethod" attribute2="{{anotherMethod}}">
Now someMethod and anotherMethod should be data, computed properties, or methods of your component, and should return either the attribute's desired value or false. In the latter case, the attribute will not be added to the element at all.
Update: Note that interpolations in attributes have been removed in Vue 2
Related
I'm reviewing this tutorial which uses a tooltip directive like this:
CASE A: No surrounding []
<p tooltip="Tooltip from text">Tooltip from text</p>
CASE B: Surrounding []
<p [tooltip]="template">Tooltip from TemplateRef</p>
I just want to make sure I understand this correctly.
If we use the tooltip directive without brackets, then the text string gets passed to the directive (Tooltip from text").
When we surround the tooltip with brackets, then the template property, which should be available on the component view (The view using the directive), gets passed in?
If we use the tooltip directive without brackets, then the text string gets passed to the directive
Yes Exactly.
For the second case, [tooltip]="template"
[prop] is for object binding to properties (#Input() of an Angular component or directive or a property of a DOM element) of the angular Component.
I've got a component called phrase, which is used like this:
<phrase *ngFor="let phrase of phraseList.phrases" [attachedPhrase]="phrase"></phrase>
Let's say now, I get one of these phrase components using jQuery. How do I access attachedPhrase?
[attachedPhrase] is not an attribute but property binding. It is supposed to be available only inside Angular application.
Although it's possible to access it as ng-reflect-* attribute, this can be recommended only for debugging purposes (this is the reason why these attributes are available in debugging mode only).
Considering that phrase is a string and attachedPhrase should be available both as component input and DOM attribute, it should be changed to attribute binding:
<phrase *ngFor="let phrase of phraseList.phrases" attachedPhrase="{{ phrase }}"></phrase>
Since attributes are case insensitive, it will be compiled to
<phrase attachedphrase="..."></phrase>
Property and attribute bindings can be interchangeable, but only if the expression is expected to be interpolated to a string.
Whenever possible, it's always preferable to not rely on DOM selectors and provide $(...) with actual reference to DOM element (nativeElement property of ViewChild or ElementRef element reference).
You can try: [attr.attachedPhrase]="'phase'".
Detailed info you can check out this site about Angular 5 directive.
I am rendering a list and then a sublist within that. I want to have a ref to my inner list which will be named something like list-{id}. However, I am not able to achieve this.
Here is the code snippet:
<ul class="scrollable-list" ref="getScrollableRef(company.id)">
<li v-for="operation in getOperations(company.id)">
{{company.name}}
</li>
</ul>
When I inspect the $refs object:
$vm0.$refs
Object {getScrollableRef(company.id): Array(13)}
I think for some reason the value is not being evaluated. Has anyone faced this?
Edit: I am trying to solve this problem https://github.com/egoist/vue-mugen-scroll/issues/14
In your example, you are specifying that the ref should literally be named "getSchoolableRef(componany.id)". That's why the $refs object contains an getScrollableRef(company.id) property with an array of 13 elements as its value.
If you want to use the result of the getSchoolableRef method as the name of the ref, you can use v-bind or the shorthand colon:
<ul class="scrollable-list" :ref="getScrollableRef(company.id)">
As you mentioned, $refs is not reactive and changing the bound value once the component has initialized will not update the property name in $refs. But, you can dynamically set the name of the ref when the component initializes.
I know we use
() for detecting event like
<div (click)="doSomething()">
or
<div (blur)="doSomethingElse()">
and {{}} for converting variable to string in template like
<div>{{a_variable_i_want_to_show}}</div>
but what do we use [()] for besides two way binding in ng-model?
Is there a generic usage?
It is two-way binding. Checkout their cheatsheet:
Sets up two-way data binding. Equivalent to: <my-cmp [title]="name" (titleChange)="name=$event">
When used with NgModel, [()] sets up two-way databinding between a component property and a DOM form element. Any change we make to the component property is automatically propagated to the DOM, and any change we make to the form element (i.e., the DOM) is automatically propagated to the component property.
When used with a component, [()] sets up two-way databinding between a parent component property and a child component property. Any change we make to the parent component property is automatically propagated to the DOM. However, any change we make to the child component property is not automatically propagated to the parent – we must use emit(). So it's a little different than NgModel.
The child component must define an input property and an output property, which is an EventEmitter. If the input property is named x, the output property must be named xChange. The child component must explicitly emit any change to x by calling xChange.emit(newValue).
The reason for the naming requirements is because [(childProp)]="parentProp" is a shorthand for [childProp]="parentProp" (childPropChange)="parentProp=$event".
If you need to execute some logic in the parent when a new value is emitted from the child, you'll want to use the expanded form: [childProp]="parentProp" (childPropChange)="doSomething($event)".
I'm using jade to template a report table as follows:
mixin report_row(row)
tr(data-id=row.c[keyIndex].v)
each cell, i in row.c
+cell_decorator(data.cols[i], cell)(data-foo="bar")
It's a nested mixin structure for a report row comprised of decorated report cells.
The problem is that the data-foo attribute is not being applied.
I've seen other issues on SO about mixin attributes but I cannot find any syntax issue with the template, it just renders while ignoring the attributes.
The documentation shows an example of passing attributes to mixins:
mixin link(href, name)
//- attributes == {class: "btn"}
a(class!=attributes.class, href=href)= name
+link('/foo', 'foo')(class="btn")
Notice that the mixin itself uses the implicit attributes name to refer to the passed attributes - in other words, the attributes aren't auto-applied, they are just sent as arguments into the mixin. You'll have to change the definition of your cell_decorator mixin to take the attributes into account.
If you want to simply apply the attributes on top of your mixin, you can use the &attributes syntax:
mixin cell_decorator(colname, data)
//- the `attributes` get applied to the td
td(...)&attributes(attributes)
+cell_decorator(data.cols[i], cell)(data-foo="bar")
Note that using &attributes like this (with a mixin call) is safe, as the values are escaped during the call.