is there any way to prevent a view from being unbound on deactivation? - aurelia

I find, even when assigning the decorator #singleton(false) to the view-model, that while the view-model does then persist as a singleton across activation/deactivation, the bindings and components, etc do not.
(I assume this is because they are stored in a container that is disposed on deactivation.)
The result is that upon every deactivation/activation of a view with a singleton view-model, the view is un-bound and then re-bound.
Is it possible to cause the bindings to persist across deactivation/activation?

This one stumped me for a good while. It also confused me as to why implementing it was not a higher priority for the Aurelia Team.
This takes a fair amount of code to get working. I have put the code in a Gist here: https://gist.github.com/Vaccano/1e862b9318f4f0a9a8e1176ff4fb727e
All the files are new ones except the last, which is a modification to your main.ts file. Also, all my code is in Typescript. If you are using Javascript you will have to translate it.
The basic idea behind it is that you cache the view and the view model. And your replace the router with a caching router. So when the user navigates back to your page, it checks first to see if there is a view/view model already created and uses that instead of making a new one.
NOTE: This is not "component" level code. That means I have tested that this works for the scenario that I use it for.
I got my start for making this change here: https://github.com/aurelia/router/issues/173 There is another user (Scapal) made something that works for him and posted it there. If what I am posting does not work for you, his may help you out.

i'm also interested in an answer to this.
maybe i'm now making a complete fool out of me but why not use aurelia-history navigate(..) command?

Related

Is there a way to store a reference to a specific component within the DOM?

The problem:
I am currently working on a file tree, more specifically on a "Selected Folder" functionality. I'm doing this to have a specific target for creating new files and folders, other that the root folder. (I'm using Vue within Electron, but this is not really relevant to the question)
Selection happens on click. Due to the nature of file trees, I use recursive components (and this limits my 'easy' access to some components).
While achieving this on the back-end is trivial, my exact problem is that while marking the selected folder with, say a different background color or bold text (by binding an id or class that has some corresponding style on my stylesheet), I need to unmark the previously selected directory.
So, how do I gain access to an indirect (due to the recursive components) child component?
What I've tried, and looked into:
Now, I know that within JS you can't store pointers or references in variables (otherwise this would've been easily achieved by storing a reference to the previous DOM element).
I have some solutions up my sleeve, but they're really tedious and not very straightforward. Previously, I had to re-render (by re-reading) specific sub-directories, based on file system updates. I achieved this partial re-rendering by propagating child function calls from the root directory until I reached the directory that needed to be re-rendered. I had to do this since the FS watcher was created on the root component.
Similarly, I could do this with the un-marking task. When I select the new folder, I start by propagating child function calls until I reach the previously selected folder, and un-mark it by un-binding the style id. Having done this previously, I know it's not a pleasant method.
Since I can get the click event target, I wondered if I could somehow store any kind of reference to the previously 'selected' DOM element and just use that reference later when I need to 'deselect' it.
Here's what my folder component looks like. I tried giving self-explanatory names to the properties, but if there's any confusion, I'll answer any question.
<folder-comp
#openFile="openFile"
v-for="folder of folders"
:key="`folder-${folder.shortFolderName}`"
:folder-name="folder.shortFolderName"
:ref="folder.shortFolderName"
:full-folder-path="folder.fullFolderPath"
:local-directory="recursiveScanDir"
:indentation-level="indentationLevel + 1">
</folder-comp>
The propagation method I used was necessary previously since all I had was an event File System path, unrelated to my Vue structures, and so I needed to somehow translate traversing that path. Here, though, everything happens only within the Vue environment, so I thought there would be some sort of way to deal with this easily.
EDIT: Well, as it happened with me in the past, just writing about the problem itself on stackoverflow helped me reach a solution.
I have a Global Event Bus set up on my Vue project, so I can bind an event listener on the currently selected folder. Once another folder is clicked (thus selected), it emits an event in the Global Event Bus, triggering the previously selected folder. This is followed by the un-marking and the unbinding of the event listener.
This is only one solution though, so the question still stands. Is this a good solution? Are there any drawbacks to this approach? Is there a better solution?
Instead of a global event bus, you can also use state management such as Vuex. When you change folders, you simply dispatch an action. This uses an command pattern, as opposed the the mentioned listener pattern. You have the choice to make this action asynchronous or synchronous as well.
There are several ways to register your listeners/watchers, from within components, or outside of them.
Using this architecture will allow you to easily add undo/redo capabilities, and also be able to navigate back and forth through your history of mutations.
You also gain the integrated debug features provided by the Vue tools in your browser.
In fact, Vuex was built exactly for situations like this, when components need to communicate with each other but the parent/child prop/emit/inject mechanisms start to become tedious and and fall apart.
There is a high probability that once you starting using Vuex, you will never look back.

Where does Dojo store required modules? Need to investigate if something is loaded

I was wondering if anyone knew how I could get a reference to the actual array or associative array or whatever data structure stores the loaded modules in Dojo.
What I am doing is this: I work in a team. We have a fairly complex page that takes forever to load because it has to wait for some Ajax calls that take a long time. Also, it relies on a lot of required Dojo modules. So my coworker devised a way to load this "template" once, and then refresh the "actual" page I am working on by use of a hashtag listener.
So anyways, in order to speed up development, I need to be able to reload custom Dojo modules I've edited. I mean, when I edit one of our modules, I don't want to have to reload everything else. Just that one module.
I was using require.undef, but that just stopped working. And I'd like to see if I can get a reference to the place where the modules are actually stored, so I can check it out in Firebug.
Thanks!!

Dojo/on. emits, widget.on etc. in Dojo 1.8/2.0

I would like to gain a full understanding of how events work in Dojo. I am actually interested in the way Dojo 2.0 works -- I am using 1.8 now, but I am only really interested in using/documenting features that will not be deprecated for 2.0.
Now... in _WidgetBase.js I read:
on: function(/*String|Function*/ type, /*Function*/ func){
// For backwards compatibility, if there's an onType() method in the widget then connect to that.
// Remove in 2.0.
This basically means that in the near future a widget's on will basically do:
on: function(/*String|Function*/ type, /*Function*/ func){
// Otherwise, just listen for the event on this.domNode.
return this.own(on(this.domNode, type, func))[0];
Which is fine. Now... in the release note for 1.8, I see:
"Widget events, including attribute changes, are emitted as events on the DOM tree"
The release note point to this: http://livedocs.dojotoolkit.org/quickstart/events#widget-events-published-to-the-dom Which "sort of" explain things, although the document seems to be outdated (it still talks about aspect for "plain object").
So, my question: is there a spot/bunch of pages/tickets that would describe the current updated way in which the whole events thing works?
My current understanding (for Dojo 2.0):
on: 100% delegated to on.js
emit: when you run randomWidget.on('something', function(){}):
-if randomWidget has 'onsomething', it will simply run that; <--- will this go away with 2.0?
-Otherwise, it will delegate to on()
So, it's all about understanding dojo/on. That's when I get confused: reading the source code, on.js seems to delegate functionality to the widget itself (which... I just wrote above, will simply delegate to dojo/on from 2.0...?!?). Unless the bit that delegates to the object is destined to disappear...?
Also, I am used to writing widgets with templates, and then add items where I do data-dojo-attach-event="onclick:_click" where I make sure a function is called when somebody clicks on it. With the new on() system, will this change? (I mean, is all events propagates to DOM, is the opposite also true?)
So, can somebody shed some light on this? I feel a little uneasy at the moment, adding events and doing things, because I am not 100% sure of what is going on.
Thank you!
Gosh that was a while ago...
Since then, I wrote this:
https://github.com/mercmobily/writeups/blob/master/dojo/widgets_containers_on.md
Which explains pretty much the whole lot!
Merc.

confusion in using YII CHtml::link and CHtml::image instead of HTML

I have started an application in YII, I want to use proper standards of YII but am just bit curious about the use of its CHTML Class. I think that using CHtml::link() or CHtml::image() instead of normal HTML code <a></a> and <img src... /> will cost more time to application on server side. I tried to look for some reason to use it but yet not success in finding any good resource on why should I use it and how its beneficial then traditional HTML. Like I can use all those methods for defining paths to actions in normal HTML code then why use it
any help or reference for clarification would be appreciated
Thanks
Let's talk about CHtml::link(). Its main advantage is that you can indicate a controller route and send some get variables by simply passing an array as paramater. Lets say you wanna go to the eat() action of your LivingController, with the variable 'meal' and its value being 'hamburgers'. It could simply be done like this:
> CHtml::link(array('LivingController/eat', 'meal'=>'hamburgers'));
If you want to express this using <a></a> only, then I don't need to tell you how much harder it would be. In addition, we should remember that a link generated using CHtml::link() will always work, even if you change the url format. That wouldn't happen with <a></a>: you would have to rewrite the url every time you change the url format.
The advantages of CHtml::image() are less clear, at least to me. Sincerely, I think it's just a matter of encapsulation.

Rails3 Engine helper over-ride

So I have a Rails 3.0 Engine (gem).
It provides a controller at app/controllers/advanced_controller.rb, and a corresonding helper at app/helpers/advanced_helper.rb. (And some views of course).
So far so good, the controller/helper/views are just automatically available in the application using the gem, great.
But I want to let the local application selective over-ride helper methods from AdvancedHelper in the engine (and ideally be able to call 'super'). That's a pretty reasonable thing to want to allow, right, a perfectly reasonable (and I'd think common) design?
Problem is, I can't seem to find any way to make it work. If the application defines it's own app/helpers/advanced_helper.rb (AdvancedHelper), then the one from the engine never gets loaded at all -- so that would work if you wanted to replace ALL the helper methods in there (without calling super), but not if you just want to over-ride one.
So that kind of makes sense actually, so I pick a different name. Let's call my local one ./app/helpers/local_advanced_helper.rb (LocalAdvancedHelper). This helper DOES get loaded, if I put a method in there that wasn't in the original engine's AdvancedHelper, it is available to views.
But if I put a method in there with the same name as one in the engine's AdvancedHelper... my local one NEVER gets called. It's like the AdvancedHelper (from engine) is earlier in the call chain than the LocalAdvancedHelper (from app). Indeed, if I turn on the debugger, and look at helpers.ancestors, that's exactly what's going on, they're in the reverse order I'd want in the ancestor chain. So AdvancedHelper (from engine) could theoretically call 'super' to call up to LocalAdvancedHelper (from app) -- but that of course wouldn't make a lot of sense to do, you'd never want to do that.
But what I would want to do... I can't do.
Anyone have any ideas, is there any way to provide this design, which seems perfectly reasonable to me, where an app can selectively over-ride a helper method from an Engine?
Anyone have any explanation of why it's working the way it is? I tried looking at actual Rails source code, but got lost pretty quick, the code around this stuff is awfully abstract split amongst a bunch of places.
This is pretty esoteric question, I'm pessimistic anyone will have any ideas, I hope you surprise me!
== Update
Okay, in order to understand what part of Rails code is being called where, I put a "def self.included ; debugger ; end" on each of my helpers, then in the debugger I can raise an exception to see a stack trace.
That still isnt' really helping me get to the bottom of it, the Rails code jumps all over the place and is pretty confusing.
But it's clear that a helper with the 'standard' name (ie WidgetHelper for WidgetController) is called by different rails code, to include in the 'master' view helper module for a given controller, than other helpers are. I'm wondering if I give the helper a different name, then manually include it in my controller with ("helper OtherNamedAdvancedHelper"), if that will change the load order.
We can use Module#class_eval to override.
In main app,
MountedEngineHelper.class_eval do
def advanced_helper
...
end
end
In this way other methods defined in engine helper are still available.
Thanks for your elaboration. I think this really is a problem. And it is still present in Rails 3.2.3, so I filed an issue.
The least-smelling workaround I came up with is to do a "half alias method chain":
module MountedEngineHelper
def advanced_helper
...
end
end
module MyHelper
def advanced_helper_with_extra_behavior
advanced_helper
extra_behavior
end
end
The obvious drawback is that you have to change your templates so that your helper is called. At least, you make the existence of extra behavior explicit there.
These release notes from Rails4 seem enticingly related to this problem, and potentially note it's been fixed:
http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#helpers-loading-order