In angular we could do something like {{content?.body}} and it will render the content body if it exist in your data.
This doesn't seem to work in Vue. Is there a way to achieve this or i have to check manually.
In Vue you can use v-if directive. For example;
<div v-if="content.body">
{{content.body}}
</div>
See for more at Vue official docs
This syntax does not exist in vue.js and it will probably never exists according to the creator of Vue.js (see this post)
However you could use get from lodash combined with computed property to simulate this behavior :
computed: {
nestedProperty() {
return get(this, 'here.is.my.nested.property')
}
}
But the easiest way is probably to just add v-if directive to your template to check that property exists
I’m guessing you’re looking for a similar approach to optional unwrap from swift or safe call operator from kotlin.
Neither JS or Vue.js support this.
Your safest bet is to use a v-if on the entire chain
<span v-if=“content && content.body”>
{{content.body}}
</span>
Related
I am new to Angular and was not sure if this is the recommended syntax in Angular. In AngularJS, we can do one-time binding in this way:
<p>{{::myVar}}</p>
In Angular, I know we can do this.
<p [innerText]="myVar"></p>
My first question is, is this the only way to achieve {{::}} in Angular?
What if I have this situation in AngularJS:
<p>{{::myVar}} is a variable</p>
I have tried something like this
<p [innerText]="myVar + 'is a variable'"></p>
It works but again is this the recommended syntax?
in angular there are three ways of one way data biding from the component to the template:
Interpolation {{myVar}} => recommended use case: <p>{{myVar}} is a variable</p>
Property binding [attri]="url" => <img [src]="url">
bind-target="myVar"
EDIT: one time binding on the other hand is a feature we used to have in angular 1 and you can replicate it in angular using ChangeDetectionStrategy.CheckOnce
check the official docs here
See twiddle here: https://ember-twiddle.com/2150099882893760cef237ff2bd22e85
Basically, in crit-service I create Ember Objects "Crits" and "Crit", and fill them with some data.
The crit-service is used by two different components, which basically do the same thing: display the Crits.
The problem is that the "change" buttons do not work. By debugging, I see that the values are changed, but the view is not updated. Why is this? Since Ember.Object is Observable, shouldn't setting a value notify the template? And most importantly, how can I get this to work?
P.S. I've seen a workaround by using Ember.A() instead of Objects. However, this would add boilerplate, as my data model is really objects and not arrays of key-value pairs.
This seems to be an issue with the {{#each-in}} helper which does not reload on changes. A quick fix is to use the {{get}} helper.
So instead of this:
{{#each-in obj as |key val|}}
{{key}}={{val}}
{{/each-in}}
Do this:
{{#each-in obj as |key|}}
{{key}}={{get obj key}}
{{/each-in}}
However, this will never work if you add additional properties.
here is a working twiddle with that solution.
Another solution that will always work is to call .rerender() on the component. This is save thanks to glimmer, which does only update the parts of the DOM that have changed. However, you would have to call it on your common root component of the two components, or on both components.
So I have this computed property inside my component.js: contexts: Ember.computed.oneWay('myService.contexts'),
And I am able to get the content from another action
openHelp(){
console.log(this.get('contexts'))
alert(this.get('contexts'))
}
}
But when I try to use the computed property in Handlebars ({{contexts}}) it's just blank.
I created an Ember Twiddle for this question: https://ember-twiddle.com/38de64d58dcf3298df6d4176f15cbc0e?openFiles=components.my-component-help.js%2Ctemplates.components.my-component-help.hbs
If I have an array foo: [ 'foo','bar'] and I do {{foo}} it outputs in handlebars. But if I make foo a computed property that gets [ 'foo','bar'] from and do {{foo}} I get nothing.
Here's the solution: https://ember-twiddle.com/e9c2ef05e27013a389e0b2bfdaec3d40?openFiles=services.my-service.js%2Ctemplates.components.my-component-help.hbs
There were two issues:
contexts is an array. When you console.log or alert it, those methods internally in some browsers JSON.stringify the object for you for your convenience. Ember will not do that. You need to format the array yourself or, as I did, each over it. For debugging purposes, feel free to use the log helper.
Computed properties on arrays are watching for array mutations through Ember's methods such as pushObject and removeObject. Simply using push or splice won't update the computed property.
Can't comment on the above answer which is correct because I don't have enough reputation, but I wanted to add a link to the documentation relating to Ember's observable methods for enumerables:
https://guides.emberjs.com/v2.5.0/object-model/enumerables/
In my app I can localize most of strings via tags, as it is described in l20n.js docs. But sometimes I have to localize dynamycally created strings. Like: document.getElementById(id).innerHTML = "some text";
I use Polymer and custom web components, so the main goal is to create one function for any localization case.
If i try document.l10n.get(string);, I get TypeError: document.l10n.get is not a function.
What is the best way to do it? Could not find the solution in official docs.
Since document.l10n is an instance of the L20n's View class, you can use the formatValue and formatValues methods for your use-case. Please see the documentation for details.
Both methods return promises so you'll need to do something like the following:
document.l10n.formatValue('hello', { who: 'world' }).then(
hello => document.getElementById(id).textContent = hello
);
You can assign to textContent or innerHTML. Keep in mind that L20n allows for HTML in translations and it only sanitizes them when using the declarative data-l10n-id approach. So if you want to manually assign to innerHTML you might want to make sure you trust the content of the translations. In the future I'd like to add a special API to apply translations to DOM elements using the same sanitization as the declarative method (bug 1228021).
The idea is to be able to perform something similar to this:
{{ #each color in colors }}
<li class="{{if car.color==color 'selected' " > </li>
{{/each}}
I am aware of the fact that ember's policy is not to have logic in the templates, still, this (simple) problem is not answered to me, after a day's search.
Build a component, add the logic into a component as a computed property.
A really boring example: http://emberjs.jsbin.com/conijumego/1/edit
You can also use needs and an itemController.
Another boring example: http://emberjs.jsbin.com/taluwuquli/1/edit?html,js,output
Use classNameBindings on an Ember Component:
"If the bound property's value is a string, that value will be added
as a class name without modification"
Ember Component Docs
Working JSBin Demo
In the demo I am defining the value for the class name for the component within the template, but as you can see in the component js, the value could come from anywhere ie., Model data, an array declared in the component etc. No need for an item controller. That approach is being deprecated anyway. We are advised to stay away from controllers in order to have a clear upgrade path to Ember 2.0