Using a computed property from a vuex getter in a module - javascript

I have this demo: https://codesandbox.io/s/runtime-bash-61mfo
I´m working with the rootState all the time, but I need find the actual element across all the elements with it´s id, so I created parentItem for this.
There are any way to access to parentItem in the myProperties getter?? I need this to later use mutations and actions across this getter to change the rootState parent item.
If I use the Method-Style Access I have to put it in the alert.js store and I cannot have access to the parentItem computed property…
Besides, in every other getter/action/mutation should send the ID to pass again to the correct getter to obtain the parentItem, when I already have the id thanks to the props…
Any idea how can accomplish this?
I can change all the structure if it´s required, but I don´t find any better way to structure the data...

Related

Display react component name in attribute

While working with React, i would like to display component name in an attribute of the component. E.g. if I have a component <LoginBox /> I would like it to be rendered as
<div data-react-name="LoginBox">...</div>
But I want this to be done automatically for each transpiled component. Reason for this is automated testing when I'd check for rendered elements in HTML/DOM, currently a component is not differentiated by the name in rendered HTML.
I thought I'd write a babel plugin, but I have no idea what visitors I'd use and how to make it robust enough. I tried google for such a plugin but I have no idea how it would be called and found nothing useful.
So is there any plugin or any way to achieve this?
Thanks
Now after a year, as I'm rethinking, it should be quite easy.
For more details on writing plugins see handbook.
Use ASTexplorer to inspect what AST would your code result in. And then, for generated tree, prepare visitors. So e.g. with code:
<div><Custom some-prop="prop">Some text</Custom></div>
we would infer, that we need to use visitor JSXOpeningElement and alter node's property attribute. To this property - array we would add a new element that we would create by Babel.types.jsxAttribute(name, value). We will get the name of tag from node's property .name.name (the name string is nested inside name object). We also need to use appropriate types. So it would look like this:
module.exports = function(Babel) {
return {
visitor: {
JSXOpeningElement(path) {
const name = Babel.types.jsxIdentifier('data-testname');
const value = Babel.types.stringLiteral(path.node.name.name);
path.node.attributes.push(Babel.types.jsxAttribute(name, value));
}
}
};
};
The code is tested with the ASTExplorer.

Use a Plugin (VeeValidate) in Store.js

I'm working with Vuex and added vee-validate (found here). I'm using a store object and from one of its actions, I want to be able to add custom errors to the errors collection based on a server response. Is it possible to access vee-validate's global errors (ErrorBag) collection that's used as an attribute typically?
According to this, I should be able to add to the errors object, but this isn't the same when I'm in my store object obviously.
For example:
<span id="error-message" v-if="errors.has('phone')">error message</span>
I'm hoping there's a way to access that errors collection. Is there a way I need to import VeeValidate to get access to what I need? Is it globally available somehow?
I would suggest that errors raised in the action be added to the store, and accessed in the component from a computed property.
That follows the one-way-data-flow principle, and since computed's are reactive should give an opportunity for the view to update asynchronously.
Perhaps:
<span id="error-message" v-if="allErrors.has('phone')">error message</span>
computed: {
allErrors() {
return this.$validator.errors
.concat( this.$store.state.asyncErrors )
}
Details need to be fleshed out.

How to properly notify data changes between siblings in polymer

I would like to have a polymer element with two sub-elements, one that produces data, and the other that performs some action when the data changes (in my case: sending a notification to a server).
To implement this, I wrote a polymer element, namely root, with the following structure (names changed to simplify the discussion):
<producer data={{foo.bar}}></producer>
<consumer data=[[foo]]></consumer>
The producer changes the data using the set('property', 'value') method, so that the root element sees the notifications. The problem is that the consumer element won't notice the changes to foo since they involve a sub-property.
To solve this, I tried using a computed binding as follows:
<producer data={{foo.bar}}></producer>
<consumer data=[[_compute(foo)]]></consumer>
...
_compute: function() {
return this.foo;
}
However this won't cause the consumer to be notified. I think the reason for this is that the returned object is the same reference (only a sub-attribute changed). Currently the workaround I've used is to use the following version of the compute function:
_compute: function() {
return Object.assign({}, this.foo);
}
This works (the consumer element gets notified), however I'm affraid it might not be the most efficient (I'm creating an object at every call of _compute) and/or elegant way. Then my question is: what is the proper way to achieve this behavior in Polymer?
Do you have access to modify the consumer element?
The best way to fix this is to have the consumer element have a multi-property observer that listens for sub-property changes on the data property.
It might look something like this:
Polymer({
is: 'consumer',
properties: {
data: Object
},
observers: ['consumeData(data, data.*)'],
consumeData: function (data) {
//Do whatever you were planning on doing with data here
}
});
The advantage of an approach like this is that your 'consumer' element just 'knows' how to consume the data object when a sub-property on it changes. Because of the lighter weight approach to data binding in Polymer, trying to implement this behavior outside of the 'consumer' element will necessarily be more expensive and more complicated, since it requires either tricking the data binding into thinking the data object is new by supplying it with a new reference to a copy or forgoing the data binding altogether and building an approach on top of events and calling methods on the consumer in response to events. So if at all possible, I would recommend trying the approach above.
Polymer's data binding does not work the same way as some other two-way enabled data binding implementations, like what you might find in AngularJS. Rather than using dirty-checking, which is extremely expensive, Polymer uses an event based 'path notification' approach. When a sub-property on a property changes, a Polymer element which has that property will fire an event to it's immediate children bound to that property, notifying them that the path 'property.subProperty' has changed. In order for consumer to act on those changes, it has to be told to listen to changes along that 'property.subProperty' path. We specify paths in our polymer observers by using the syntax above. In this case, putting data.* in our observer means we want to listen to any path off of data, so that any notified property change on the data property will trigger the observer.
As you have noticed there isn't an elegant way of doing this. The way you got it working is interesting.
An alternative way which I would expect to work would be to fire an event from within the producer element.
this.fire('data', {data: this.foo.bar});
and then have the parent/root element listen for this event and then update the data property of the consumer element.
<producer on-data="handleData"></producer>
<consumer id="consumer"></consumer>
handleData: function(e) {
self.$.consumer.data = e.detail.data;
}
Edit:
You could make a new property that you compute within the producer element. Then you won't have to do a computed function everytime you want to access foo.bar
Producer element
properties: {
foo: {},
bar: {
computed: 'computeBar(foo)'
}
}
Root element:
<produce bar="{{bar}}"></producer>
<consumer data="[[bar]]"></consumer>

How to add an item to the JsonRestStore local storage?

I'm using tree with dijit.tree.ForestStoreModel as a model and JsonRestStore as a store.
It works fine when tree is initialised. After that I want to add another item to the store manually (not from server) to update the tree.
My question is how can I do it without posting the item to server by rest, just to local storage. I used store.newItem() but without success.
I think in this situation, you probably wouldn't want to actually use a JsonRestStore. Depending on your use case, you may want to use some other type of dojo store like Memory and on initialization of your Tree, load the data from your server through some other method.
Finally I was able to figure out what fired requests to server. That was jsonRestStore.save(), that commits dirty data to server.
After I've removed it from my code, I use the following to add new data to tree:
jsonRestStore.fetchItemByIdentity({
identity: parent.path,
onItem: function (parent) {
store_cloud.newItem(child, {
parent: parent,
attribute: 'children'
});
}
});
Here I have a child node and parent one. Also 'children' attribute is used for referencing.

Ember: transition to route passing the ID instead of obj

I have some route like /ads/:ad_id and from my controller I can do
this.transitionToRoute('ads.ad', adObj)
How can I do the similar thing but this time passing the ID instead of the loaded object?
O course I understand that I can load an obj by ID first, but Ember's power is in doing lost of boilerplate for us.
Update: So, as by default Ember serializes the model to URL params by doing like
mode_instance -> { model_name_id: model_instance.id }
My trivial attempt was doing
this.transitionToRoute('ads.ad', { id: adObjId })
But when passed a model object Ember does not re-fetch it.
So, the question: I have a route (single ad view) that depends on ad ID. I have this ID as number. I want to transition to this route like if I simply entered the url /ads/ID
This can be accomplish by passing the URL to transitionTo. For example,
this.transitionToRoute('/ads/' + adObjId)
The model() method will be called with the params from the URL.
Here is a use case for this:
Transitioning from a list view to a detail view. In the list view, the records don't have any relations tied to them, but the detailed view should side-load relational data. For this reason, the models are not 1:1 between the list view and detailed view. There should be a way to transition simply using the id.
Cp
What's your use case for this? Most cases when you would want to specify an object by id, you already have the object to pass to transitionTo. Can you provide more context about what you're trying to do? I think you can probably accomplish it without using the object id.
In any case, I don't think there's a good way to do this, because when you transition via transitionTo(someRoute, someModel), the route's model hook is not called, and the model you pass in (someModel) is supplied directly to the other route hooks (setupController(controller, model), redirect(model), renderTemplate(controller, model)).
See Ember.JS Route api -- model method for more details.

Categories

Resources