I am making something similar to sheet with cells where using drag and drop i can move events, that are components, around.
Since it is possible to add component from any file like this
import event from "event.vue"
let el = document.getElementById("div")
const newComponent = createApp(event)
newComponent.mount(el)
Im trying to remove it somehow aswell, but i had no luck to find solution.
i have tried to this
let element = document.getElementById("newComponent")
element.parentNode.removeChild(element)
It's kind of working, but i can't add new component to same div because there is dataset remaining 'data-v-app' and i guess its because old component was not removed. Is there a way to do this or maybe vue isn't capable?
v-if is still the "official" way of doing things here because it uses Vue's reactivity.
Modifying the DOM is not recommended since it's imperative, like jQuery: you need to tell the language how to do things, so you need to take care of finding the selector, ask it to do things on it, and loop that process in case of an event listener or alike.
VueJS is declarative, so the API is far less complex. You tell what variable is bind to what and when the variable mutate, it will react accordingly to the changes without you needing to tell step by step what to do.
When you project grows, an imperative approach like jQuery or your vanilla JS (document.getElementById) will not be efficient because you will need to describe everything that happens once you mutate a variable. If 12 things depend on a thing, you will need pretty much the double of lines of code for each of them.
While in Vue, you will make some conditions thanks to the API and it will make those changes by itself. The complexity is then greatly reduced. On top of having powerful directives + Vue devtools to help you.
Add to that the fact that if you mix both some Vue state + imperative coding, you will have the worst of 2 worlds. You will need to do funky things to kinda keep the reactivity + will still need to write declarative code.
Hence why, people are using Vue's API + template refs only when needed.
Stay away from imperative coding: jQuery, manually selecting DOM elements etc...you will have an easier time, less complexity and more performance by far.
Vue/React exist for a reason, mainly removing complexity. Use them to their full potential.
Related
I have to render a lot of divs into DOM. So, what I did is I render the first 5 elements into the DOM first after that I render every 10 divs with 300ms interval period.
The problem is when I change into display: block I need to change something in the component. So, I try to use didRender hook for that.
Code is below
didRender() {
if(this.element.offsetParent) {
this.set('myvar', true);
}
}
But it's not working perfectly. Anyone please suggest me which is the best way to do this.
_Thanks in Advance.
It's hard to guess your use case from the question but I assume that it's about rendering a very large list of items without causing performance issues. The ember ecosystem provides bulletproofen addons to do so. The most established ones I'm aware of are ember-collection and ember-large-list. I would recommend to use one of these if they suit your requirements. Reimplementing something similar will be a lot of work. Rendering new items on a timeout basis would not scale well as it doesn't take workload of browser into account.
For your concrete question: Ember does not provide a way to listen to CSS changes. You should execute custom logic at the same place as in which you are mutating the property which triggers the CSS change. If it has to be run after render, you need to deal with Ember's runloop.
Prev function is Jquery function. Is there an alternative to this in ReactJs? I did a lot of research. But I could not reach the result.
I have tried before: previousElementSibling,previousSibling,nextElementSibling,nextSibling. They didn't solve my problem. Is there anybody who can help me about it?
$("#diagram path[marker-end*='url']").prev('text');
Does this code have a counterpart in ReactJs?
You shouldn't need jQuery if you work with React the way it's intended to:
A big difference between these two is that React works through the “virtual DOM”, whereas jQuery interacts with the DOM directly. The virtual DOM is a DOM implementation in memory that compares to the existing DOM elements and makes the necessary changes/updates. And that leads to much faster performance.
Source
Go through the docs and give it a try. You won't regret it.
The Polymer documentation suggests using a custom element for sharing some static data, like configuration. Something like <app-settings>.
I'm wondering whether it is optimal from performance point of view. Whenever such non-visual element is used it has to be created nonetheless. Wouldn't it be better to simply share the settings in a global variable or in a form of a (AMD/requirejs) module?
The same goes for purely functional tags like <iron-ajax>. If I place many of the inside my custom elements wouldn't it affect performance as opposed to simply using some existing XHR library?
No it's not optimal from a performance point of view.
Custom Elements are slowly created (and is even slower with polyfill).
I think a non-visual object gains nothing to be a Custom Element.
You're right, a simple object would do the job better. Don't get polymerized :-)
http://jsperf.com/new-vs-create-element/3
For example, I need to disable every input when the view's model isn't new (has an id).
I can do :
if(!view.model.isNew()) {
view.$('input, select, textarea').prop('disabled', true);
}
or I can go do an "if" on every input I have in my template:
<input type="text" {{# if model.id }}disabled{{/ if }}/>
If we follow the MVC (or MVP) pattern, I guess the second approach would be best, since the view logic is in the view. However, if I go with this approach and decide to change the condition that disables the inputs, I need to change it for every input in EVERY template. If I leave in the JS code, there is only one place to change.
This is just one example, but I am having similar dilemmas with alot of things. Hopefully you got an answer for that.
Cheers!
Based on your question, I'd say that you're probably running into this general problem for two related reasons -
You're using backbone exclusively, rather than a framework like Marionette or Chaplin.
Your views are "too big" and trying to incorporate too much material into a single view.
I almost never include logic into templates and that's because I almost never need to. That's because I write a lot of very small views, and piece them together to make large views. Marionette's view classes make this very easy to do, by subclassing the backbone view into different view types, adding additional utilities and drastically cutting down on boilerplate. Marionette is also very good at handling nested views, which really allow you to drill down and create the exact view tool you need for a specific use case.
It's not at all uncommon to be able to define a useful view using Marionette in 1-2 lines of code, which gives you a lot of flexibility to make very small, efficient views. The disadvantage to making lots of small views is that it's a lot of code to write, and could become difficult to maintain, but Marionette makes that disadvantage relatively insignificant. Marionette only took me a couple of days to get the hang of, and I highly recommend integrating it into your Backbone apps for exactly this problem.
When your views are big, and try to do too much, you wind up with the problem you're describing - you have to modify them too much to fit your specific needs and your code gets ugly and hard to read. When you have a lot of small views, they're very responsive and need little if any customization.
The example from your question is, I think, a border line case. My gut instinct would be to create two entirely separate views and run them under the following pseudo code:
editableView = { //definition }}
disabledView = { //definition }}
if (newModel)
editableView.render()
else
disabledView.render()
This is my gut instinct because my bet is that there are other differences between the views than whether the inputs are editable. Even if there aren't now, you may find in a few months that your needs have changed and that you'd like to incorporate some changes. The approach I suggest allows you to put those changes right into the appropriate View and not have to worry about logicking them out in a single view and deciding whether that logic belongs in the template or the view.
If you were absolutely certain that the only difference between the two views was going to be whether the inputs were editable, and that your needs are not going to change in the future, then maybe you would want to think about rendering them with the same view. If that is the case, I'd recommend that you put the logic in the javascript, rather than in the template, for the reasons you identified. But as I said, your example really is a borderline case, and in most instances I think you'll find that shrinking your view scope will really help you to see where your "template logic" belongs.
NOTE: I've talked a lot about Marionette in this answer, but I also mentioned Chaplin as another option above. I don't have much experience with Chaplin, but you may want to consider it at it as a Marionette alternative.
I prefer to do implement view logic in templates:
It is easier to change and read
Any dependency to id, element and etc can be implemented in template
List item
complex logic can be implemented in templateHelper of marionette or serializeData of Backbone without any dependencies to content of template or view
you can also implement complex logic using Handlebar Helper
Disadvantages of view logic in code are:
in case of changes to selectors (id, classes and so), all views have to be changed or reviewed
logic has to be applied again if view is re-rendered
Perhaps what you might be looking for presenter (aka decorator).
Instead of sending the template the model directly, consider sending it though a presenter, this way you can construct the attributes for the input field. Something like this:
present = function(model) {
return {
inputAttributes: model.isNew() ? 'disabled' : '',
id: model.id,
name: 'Foobar'
}
}
template(present(model));
then in your template:
<input type="text" {{inputAttributes}}>
A simple javascript widget design question.
I have started working in javascript fairly recently. And as part of my work, I intend to create a lot of reusable code; so for me javascript widgets seems like the best way to go.
However I am faced with a design dilemma, and I am not able to find the right answer.
I have a simple javascript widget, which alters the string in a html component. So my widget is somewhat like this:
(function() {
var convertString = function() {
$(".classForHtmlComponentsIWantToHandle").each(function(index, element) {
//js_fu stuff done with string fetched from "element"
});
};
var _somePrivateHelperMethod() {
//some work that would have been impossible without this helper method
};
GloballyDefinedNamespace.StringUtils = {convert : convertString};
}());
this allows me to call later
GloballyDefinedNamespace.StringUtils.convert();
Now if you would notice in my widget-ish function above, I extract all the HTML components from the DOM, that I want to alter string for. Interesting bit is that HTML will have span and divs with same css class and also textbox components with css class.
Both have a different way of extracting their value and setting new value back.
Based on my experience, if this is a widget to alter string then all it should care about is incoming object that "hold" string in a uniform manner and then based on a object expectations, my widget should be able to operate blindly.
"if it sounds like a duck, walks like a duck, then it's a duck". Kind of thing.
So effectively I would like to be able to NOT worry about distinguishing "element" object being a textbox or span in my widget. Instead wrap it into a generic wrapper.
However people have advised me that in javascript widgets the usual convention is to take care of component specific stuff within widgets. I am not convinced, as I firmly believe in programming to interfaces and not specifics. So I am at conflict.
In my example above, I don't think so the highlighted dilemma does justice to this problem, but on a larger scale this pops up as a question for me often.
I would like to hear opinion from guys, as to how to build that component independence within my widget for an HTML DOM? Is a solution to create javascript wrapper objects with same interface and then css-select them separately and then make method call as following?
(function() {
var locateAllComponents = function() {
$(".generic-class").each(function(index, element) {
//wrap element into suitable wrapper that has common interface for getter
//setter.
GloballyDefinedNamespace.StringUtils.convert(wrappedElement);
});
};
}())
Any insights and answers would be highly appreciated.
You are trying to force concepts on javascript that are foreign to it.
Programming to an interface works for for OOP, but for other language types it is a bad idea.
You can look at how jquery uses .text() (http://api.jquery.com/text/) and .val() (http://api.jquery.com/val/) and you will see that what you want to abstract they put into two different functions, for a reason.
Widgets can be useful, but at a cost of bloat and performance, so you need to look at what you are doing and ensure that you don't exact too much of a price.
So, start small, perhaps with a widget that can work on form elements, and see what you can do reasonably within the object, but you will find that at some point it becomes very helpful if either the API user or the API developer creates functions to pass in to your widget, to get the additional functionality.
But, all of this will impact performance, so as you work, do some unit tests so you can look at changes in performance to help guide you on what changes are worth the price.
You may want to start with looking at the JQuery UI widgets though, and see what they did, rather than just re-inventing the wheel for no reason.