textContent/innerText/innerHTML in angular binding - javascript

I'm trying to prevent content replacing for angular app in my custom component, it happening when on custom component like <my-component></my-component> placed BOUNDED property textContent/innerHTML/innerText, e.g. <my-component [textContent]="example"></my-component> and my component just dying without message.
as i know for now angular aplying content replacing with bounded defualt propertys in the moment afterViewInit in the same moment where it apply interpolation it means i can't split them by checking something like elementRef.nativeElement.textContent/innerHTML/innerText in the afterViewInit(or any else).
also i can't get it by getAtribute/hasAtribute you will got null/false if you will try to do this on bounded textContent/innerHTML/innerText (maybe it's bug idk can some one answer for that pls)
so for now i have two main idea how can i do this
i can check some unique element with BEM notation still exist inside my component in afterViewInit but it's to local.
i can catch bounded property by input field with the same name as property but it's to dirty even if i need check only one but i wanna check them all(3).
(my senior colleague prompted me) i can check elementRef.nativeElement.children !== 0 that looks good but we will be ignore innerHTML with elements inside
maybe you have better idea how i can to do this
i use angular 12 with ivy mod and i was't test it on other version

Related

model input (textfield) statemachine in xState

Would love to read your thoughts on how you would model a input (textfield) with xState.
According to an input ux article a textfield could have following states:
Input text fields can have one of the following states: default, focused, error, and disabled. All states should be clearly differentiated from one another.
This makes sense as other libs like Material UI uses more or less the same states.
Im wondering how to model this.
Let me just write down some thoughts:
I think its obvious that the value should be part of the xState context as it could have any value
the mentioned states makes sense as well
Now the part where im not so sure: lets say we have an inline validation (onChange) which says the textfields value is ok and for that we set want to set with css a class "valid" which gives the textfield a green border.
We would need either a state transition from default to default_valid (not just valid because we are still in the default state) ... the same applies for default_invalid ... and aswell for some more combinations which would possible end in a state explosion.
model it in xState as a child state and access it via default.valid or default.invalid ...
In both scenarios we would need in the textfield component another mapping which reads something like
(just pseudocode)
switch(state) {
'default.invalid': setColor(red), setDisabled(false)
'default.valid': setColor(green), setDisabled(false)
'default.valid.submitting': {
setColor(green)
setDisabled(true)
}
Im really not happy with this approach to manage the state in the component and time in xState machine. This just seems wrong to me.
I would prefer to just use the input machines states ... which works well for some default like, default, focused ... but as soon as the field is "in 2 or more states" it gets a mess.
One way would be to just keep some high level states and write the additional ones in the context and just pass it to the textfield? (sounds not that good either tbh)
So would love to hear your thoughts how you would model something like this.
You can use state.matches(...) to clean things up, and/or you can place those actions directly in the states they're relevant for, e.g., in entry or exit.

How to look for the parent of an object - Eslint selectors with espree

Currently I'm working on some code to disallow the use of global constants in a user input area that allows them to use formulas.
I'm using espree as a parser.
Currently I have some working code to find the use of an global or the immediate child of a global but if I set something like Parent.Child0.Child1 the rule stops working.
I guess it would be easier to find that given any number of childs if the parent is in the blacklist we should ban the sentence but I don't know how to access it.
It may be quite simple but I did not find anything regarding this topic, I took a look on this page for reference but it did not have the answer: https://eslint.org/docs/developer-guide/selectors
const allowedReadOnlyGlobals = ['object1', 'object3', 'object3'];
allowedReadOnlyGlobals.forEach(globalObj =>
disallowedSelectors.push({
selector: `AssignmentExpression[left.object.name="${globalObj}"]`,
message: `It is not allowed to replace members of the '${globalObj}' object.`
})
);
I expect some rule like this one, but I'm not sure if that will exist
selector: `AssignmentExpression[object.parent="${globalObj}"]`,
(The rest of the code I expect it to be the same)
After a lot of research the selector query was the following:
selector: `AssignmentExpression[left] MemberExpression[object.name="${globalObj}"]`,
I expect this helps someone in the future.

How to get the component that rendered a dom element with Vue.js

How to get the component that rendered a dom element with Vue.js ?
For example, suppose you want to retrieve which component "owns" a dom element that the user has selected, how would you do ? (it seems to be implemented in the dev tools, but I can't find a way neither in the documentation, neither on SO)
(I mean, given the DOM element, I know how to retrieve what element is selected)
DISCLAIMER : This may not be the right solution for common use cases. Always prefer handling event & co. in the root component using direct sub-component reference if you can
I do not know if this is safe or officially supported, but assuming you're trying to access the component from some external-to-Vue code, this will return the VueComponent object for a given DOM element (substitute your own DOM selector as needed):
document.getElementById('foo').__vue__
If used on the app's root element, it will instead return the Vue constructor object.
(This appears to work in both Vue 1.x and 2.x.)
This is possibly not the most elegant solution, but you can use mixins to achieve this:
var elemOwner = {
mounted: function() {
this.$el.setAttribute("isVueComponent", this.$options.name);
}
};
As long as you set the mixin to the components you need it in, when you click an element you can test the attributes to see if there's a component name in there.
See this codepen for a fuller example: https://codepen.io/huntleth/pen/EpEWjJ
Clicking the smaller blue square will return the component name of the component that rendered it.
EDIT - It should be noted though that this obviously would only work if the element is actually inside that components root element. I think that would be the case for almost all uses.
Getting this.$parent refers to the parent of a component.

When using vue-virtual-scroller where does content-tag and main-tag come from

I am trying to understand the vue virtual scroller. I noticed in the demo there are a couple HTML attributes it uses...
<virtual-scroller v-if="scopedSlots" class="scroller" :item-height="itemHeight" :items="items" main-tag="section" content-tag="table" :buffer="buffer" :pool-size="poolSize">
link to the specific line on source code
Where does this ability come from and where is the documentation for it?
These are props declared in ../src/components/VirtualScroller.vue.
Both "content-tag" and "main-tag" are props of type String, meaning you can pass your choice of html elements. In your copied example, "section" and "table" is being passed to each prop, which is simply a string. If no value is passed, it would default to "div", which was set here: https://github.com/Akryum/vue-virtual-scroller/blob/master/src/components/VirtualScroller.vue
The string can also be passed dynamically, as they do for :item-height="itemHeight", where you would have :main-tag="mainTag" or :main-tag="anyCustomMainTag". This would allow you to set mainTag or anyCustomMainTag to your string value, which would also override the default div.
Breakdown:
v-if - vue directive
class - normal html attribute that you probably already know.
item-height- computed Method.
items - data object property.
buffer - data object property
pool-size - data object property
please notice that item-height for example is written as kebab-case on the html side, but should be written with camelCase on the javascript side. like so: itemHeight
about the content-tag, main-tag - worth a shot to ask the developer on github. those are not part of official vue api, nor part of html spec.

AngularJS Directives: Using return in the `pre` function

I've been trying to track down a bug in ngGridv2.0.14 where the "gridID" class is not being set on my ngGrid classed element, even though the dynamic stylesheet is being appended to my document header, and I found something kind of wierd...
This bug causes the columns to appear "on top of" each other...
In ng-grid-2.0.14.debug.js there is a directive created called ngGrid (of course!). The directive uses the suggested "directive definition object" form. They define an inherited scope by defining scope:true and they declare a compile function which returns an object structure containing ONLY the function pre and DOES NOT declare the function post.
What is weird is that there is a return statement within this pre function, and I cannot find documentation about return statements within a pre function. The function ends up in Angular's "processQueue", which I believe could be Deffered.$$state.pending (I am tracing the call stack to find this, so I am not sure). During a $digest loop, angular tests these array indexes as functions and invokes them.
The ngGrid function that is being called, which can be found at ng-grid-2.0.14.debug.js line 3318, does a lot, and most of these things are working, such as $destroy cleanup logic, $complie($scope) of the gridTemplate, event listener establishing, and, most importantly, the addition of two very specific classes to our directive's iElement which appears to still be "in scope." This is the part that is failing.
They are adding a class to the iElement by:
iElement.addClass("ngGrid").addClass(grid.gridId.toString());
Sometimes this works, sometimes this doesn't...
Sometimes the element picks up the classes "ng-scope ngGrid ng[0-9]{13}" (e.g: ng-scope ngGrid ng1453913625179), and sometimes it does not, even when I have stepped through the function and watched the line of code that adds the classes get executed.
Further Investigation!: If I place an ng-if="true" on the parent node of my "ngGrid element" (the element that instanciates the ngGrid directive by attribute), then eveything works!
My Question: Does appending classes to an element within a $digest loop have issues or any reason why this would work sometimes and not all the time? Also, can you find documentation on setting return values for pre? I couldn't find anything about the return values here. Finally, why does setting ng-if="true" on the parent of iElement fix the issue of the class names not being appended to iElement's class list? Thanks!

Categories

Resources