I have a general question regards where I should do view element addin initialzation. Say for instance I have a typeahead plugin that requires initialization like so.
$(element).typeahead();
Using Backbone.Marionette where is the best place todo this type of view specific code? My original thought was to override the onRender() method in my view class and do this specifically everytime for elements I know about at design time. However, I would like a more general approach like monitoring the newly added dom elements and checking if element has an identifier like 'data-typeahead' and then automatically initialising it. However, I don't know any jQuery function that would do this? Or even if this is a realistic idea in terms of the overhead of dom parsing especially on mobile devices?
Any thoughts / ideas on how to solve this or where to best place to do this sort of code would be awesome!
Thanks
Jon
For those interested I used #Trond suggestions and implemented view init statements in the onShow method.
Related
I am new to knockout, so going to fire a lot of questions. But I'm not new to data binding. So I am knocking my head on the difference between my expectations and reality. Here is a very basic question about applyBindings.
It looks like applyBindings has the parameter "view model", which is to me the domain object graph (as javascript objects) plus perhaps additional helper things added for the purpose of the view creation. But what I am completely missing at first is the scope of the bindings! I expected this to be applied to the current parent DOM element. But no, it is applied globally, in the entire page!
So is the expectation that in one HTML document there can only ever be one view model? This is very surprising to me! How am I supposed to create a single page web app where I have one panel showing the address book, another panel showing my appointments, another panel showing one loan application to review, and yet another showing the underwriting of another loan? They are all completely different things, am I really supposed to link them all into a single view model???
In my expectation, you bind a javascript object to a DOM element, and everything in there renders it. With every new nested DOM element, the focus object may change. It may be flowing out of some foreach binding from the parent's object. But then two sibling (or cousin) DOM elements might be sitting side by side and having completely different view model, and also a different life cycle. Like while I am in my underwriting workflow, I quickly need to bring up an address book or my calendar. All of it in a single page app. There should be no global interference between different view models used by different unrelated DOM elements.
And yet here we are with knockout I see it has only one ko.applyBindings(viewModelObject) for a the entire page.
What am I missing? What is preventing us from modifying ko.applyBindings to take two arguments, the view model-object and the DOM element in which to show it? I could try doing that, but I am afraid if knockout has been designed in this global mindset, there might be lots of issues running the knockout machinery more than once on the same page?
I'm sorry if I am frustrating people by shooting an answer already. But since I have a very urgent project I need to try to resolve my issues ASAP, and I am reading the knockout source code, which is quite nicely organized and uses good names, so it's quite intelligible; therefore I have found the answer myself.
The answer is that, yes, you can applyBindings to a parent element that you choose. The document.body is only the default if you don't say anything.
Therefore, from now on, I shall (tell my team to) always call applyBindings with the second argument specified for the rootNode. Like this:
<div>
... all my UI elements for this thing ...
... then last element in this div:
<script type="text/javascript">ko.applyBindings(viewModelObject, document.currentScript.parentElement);</script>
</div>
so, that way I can have multiple view models each in their own DOM element.
And additionally also, I was wondering, does knockout not somehow assign the model object to the DOM element? I could do that in my script tag too:
<div>
... all my UI elements for this thing ...
... then last element in this div:
<script type="text/javascript">
const viewElement = document.currentScript.parentElement;
viewElement.viewModelObject = viewModelObject;
ko.applyBindings(viewModelObject, viewElement);
</script>
</div>
and this allows me then -- if only for debugging -- to find the current view model object on the DOM element that is the root of a view. (It would be nice if that would happen with all other descendant bindings too, but that is perhaps the subject of another question.)
In fact, I decided to put into our general configuration a hard replacement of the ko.applyBindings function:
ko._applyBindings = ko.applyBindings;
ko.applyBindings(viewModelObject, rootNode, extendContextCallback) {
rootNode = rootNode || document.currentScript.parentElement;
rootNode.viewModelObject = viewModelObject;
ko._applyBindings(viewModelObject, rootNode, extendContextCallback);
}
now I don't even have to convince my team to do it this way, they will automatically, even without being aware of it.
I'm a Polymer novice, but I guess what the answer will be...
Recently I came across with this issue: I got to loop through a collection of elements (using dom-repeat) and display its contents. But every element has a unique display and bindings, making it almost impossible to display each element dynamically. The ideal scenario would be to load a different component for each display type, but it looks like there is no easy way to achieve this.
Some options I have been thinking of were the following:
Using dom-if but it would add crap to my resulting HTML.
Is there a dom-switch? If it were something like that and didn't leave empty template tags (as it would do with dom-if) it would be nice.
It's possible to load a component dynamically? Using something like this: <[[item.type]] item-configuration=[[item.configuration]]></[[item.type]]>
Any other ideas? I would really appreciate any ideas or solutions or at least a workaround for my issue.
TL;DR; you can't
Polymer (and Web Components in general I guess) are best when used in a declarative way. Out-of-the-box your best solution is dynamically creating elements and adding to DOM or messy use of dom-if.
(potential) OPTION 1
I guess you could fairly easily implement a dom-switch element to work like
<template-switch switch="[[some.value]]">
<template-case case="10">
<element-one></element-one>
</template-case>
<template-case case="20">
<element-two></element-two>
</template>
<template-default>
<element-one></element-one>
</template-default>
</dom-switch>
I wrote this off the top of my head. There are multiple ways to implement such an element. A crucial decision is whether to use <template> internally or not. In this plunk I've implemented such element without templates but simply using content distribution.
OPTION 2
There is also Polymer.Templatizer.
Faced with a similar issue of choosing element to render dynamically I created this Plunk as a proof of concept.
As you see, you extend the <template> element with custom rules, which match against a model. You then bind the matched template's nodes with the model using Polymer.Templatizer.
Thanks to Templatizer, you don't have to pollute your actual element with conditionals and still get full binding functionality.
I'm working on a more feature-complete solution. If you're interested I could move it to a separate repository and publish.
In order to navigate through the elements/components hierarchy of EXTJS , I need to see what is up and what is down from any point like an element. Too often I go the wrong way and it takes me hours to figure out the path of a component/element (from to). Opening up the debugger and doing it through dom is abominable. Is there a nice utility or way in EXTJS to xray view the hierarchy in some way? And if you are sure that there is not, please let me know how you do it.
Let's say I start this way:
var panel = Ext.ComponentQuery.query('panel[itemId=dateOfDeathPanel]')[0];
And I need to get to a textfield or button, what is the pro's way of navigating the hierarchy, other than opening up the files and wasting precious time deducing how the components/elements are arrayed?
Many thanks for your help.
DK
Well, this question is quite big and not easy to answer because it depends on the architecture / pattern you choose as well, mvc, mvvm, etc..
I really like to use viewcontrollers to access the components using the reference config object or itemId, described here:
http://docs.sencha.com/extjs/6.0/application_architecture/view_controllers.html
Beside that you can install in Chrome the AppInspector plugin from Senchalabs, this can help you navigating through the component tree, stores and more.
Repo:
https://github.com/senchalabs/AppInspector/
Chrome store:
https://chrome.google.com/webstore/detail/app-inspector-for-sencha/pbeapidedgdpniokbedbfbaacglkceae
Can you use beside that the .up and .down selector in extjs:
extjs using up and down methods
newbie question.
I've read some of the W3Schools, I also read a lot from other sources on the internet, however I can't find what I need, and I'm sure it's quite simple to you.
I'm using ASP.Net, and I want to add to my website, multiple items, which every item hold a picture, and some other information, including links. I'm pretty sure I don't need to write the code for every item in the HTML source, and I don't know exactly how to implement my this.
The basic idea is that my items will be imported from a Database that I create in visual studio, and I want to style my webpage so they would appear in a certain formation, I thought I might need to use Javascript or CSS for this, hope I'm not mistaken.
Javascript isn't some sort of magician that will render all your stuff on its own. However, you can use it to attach a template to every of your items.
What you have to do is :
Create a base HTML template for 1 of your item that can be applied to all of them
Create a Javascript function that will attach thoses CSS classes and HTML attributes to every element out of your DB (or you could use a templating frameork .. since there's a lot of them I'll let you look for it on Google. It's pretty easy to use)
On page load or whatever event you want to bind on, you call your function which will attach the CSS and HTML to every element out of your DB and will render it on your page
Enjoy what you've done.
I hope this helps. Good luck ! ;)
I'm making a widget that has a tabContainer in it, which needs to be started up after it's inserted into the DOM and ready.
However, my class actually responds with a view that you can instantiate yourself. Therefore, I want to have an 'onPlace' event or 'onComplete' event of some sort that starts up the tabContainer once it's been placed.
Can anyone lead me in any good direction on this? Can't seem to find much dojo / dijit documentation out there that can help!
Okay, after looking into the source code a bit I found this out:
If you widget inherits from dijit/_WidgetBase (mine did), you can overwrite the startup function which will happen after it's rendered.
For example:
tabContainer: value,
startup: function() {
this.tabContainer.startup();
}
I'm not sure if this is the most elegant, but if you have any input or solutions please feel free to add/comment/answer!