Backbone replace view / get view position - backbone.js

I have an application which is not optimally designed. I don't have time to re-write it, and need to find a solution to the following problem:
In my application new elements may be added to the collection, and there is a function in the collection view which decides whether to insert the new element at the top or the bottom:
if (someLogic) {
this.$container.prepend( newEl );
} else {
this.$container.append( newEl );
}
There is also the possibility to edit elements; in this case the application first destroys the old view, if there is any:
item.trigger('destroyView');
and then renders it. Somehow it was rendered in the same place it was previously:
+--------+ +--------+
| x1 | | x1 |
+--------+ +--------+
| x2 | | x2 |
+--------+ ====> +--------+
| x3 | | x3a |
+--------+ +--------+
| x4 | | x4 |
+--------+ +--------+
Now, due to some changes, the edited element is rendered either at the top or at the bottom of the collection view.
My question is: how do I render it in the same place it was previously.
I tried to add a listener on the model as explained here, but some of the programmatic logic seems to be broken.
Is there any way to:
replace an existing view with a new rendered one?
OR
by iterating the container view elements, get the corresponding models? (the models have an attribute which indicates order, so I can use insertAfter or insertBefore)

I figured out that the solution is easier than I thought.
In the place I get the new model, I can determine whether the model exists already or not.
In case it exists, instead of destroying old view and render it again, I simply send a trigger so the view is rendered again, in the same place it was:
container view:
var model = this.collection.findWhere({id:newInteractionData.id});
if (model) {
model.trigger('render');
} else {
// here comes the old 'render' code
}
item view:
this.listenTo(this.model, "render", this.render);

Related

When a Resource Event Occurs Logic App Triggered Twice

I've created a Logic App triggered when a resource event occurs, but it's triggered twice for each blob created.
Logic App details:
Trigger type: When a resource event occurs
Subscription: abc
Resource Type: Microsoft.Storage.StorageAccounts
Resource Name: abcxyz
Event Type Item - 1: Microsoft.Storage.BlobCreated
Prefix Filter: /blobserv/default/subfold
Suffix Filter: .pdf
From what I can find online, an event is fired when writing to blob is initiated, and another event is fired when the writing has been completed. This would explain the Logic App being triggered twice.
I tried to update the Logic App to filter on blob size, but it appears to be the same value for both triggered runs.
Get Blob Metadata using path (v2):
Size: 41556
So, is there a way to know if the Logic App is firing off the creation or completion event or another way to filter out the creation trigger?
I might have narrowed down your issue.
Every Put Blob Container Operation triggers two events (Started and Succeeded)
| Operation name | Status |
| Put blob Container | Succeeded |
| Put blob Container | Started |
Adding filter at Logic app level
Operation name == Put Blob Container
and
Status == Succeeded
should address your concern

AngularJS can't find nested template files

I'm working with AngularJS and am having a simple but odd issue. AngularJS is unable to locate my template file if it is in a subdirectory of a specific directory.
The below project structure is what I wish to have. I reference myFile.html by using the templateUrl property on a component templateUrl: "/MyApp/posts/myFile/myFile.html" With below structure and this import, AngularJS throws an error.
public
| javascript
| MyApp
| posts
| app.js
| index.html
| myFile
myFile.html
If I reformat my structure to the below, and change my import to templateUrl: "/MyApp/myFile/myFile.html" everything works
public
| javascript
| MyApp
| posts
| app.js
| index.html
| myFile
| myFile.html
Please don't suggest that I check the spelling, and file path. I've done that a million times and it just never works if it's in a sub directory of the posts directory

How to achieve a snappy, cascading UX via AngularJS + ui-router

root
/ | \
/ | \
/ | \
header content navbar
|
|
library (abstract)
/ | \
/ | \
/ | \
Authors Books Movies
Using my beautiful graphic above I would like to explain a few things:
header has some API data to retrieve about the user (e.g. GET /user/me)
Authors has its own GET /authors it uses to populate that view
Books and Movies are the same as Authors, they are just their own state
Now this is what I want:
I want a cascading layout whereby the main layout of the page can be loaded first, then the "library" application can be loaded on top of it without any "lag" or blocking of the UX.
However, with how ui-router seems to work today, if I have 1 resolve in this entire application and I place it in the "library" state, what happens is the "header" and "navbar" states are blocked until the resolve completes. What I would expect to happen is the parent states load first with their views, then the "library" state blocks on the resolve. That way you could see the navbar and header in the browser as soon as the page is loaded, but you would get a loading bar or spinner until the "library" resolve finished.
Any easy way to achieve this functionality would be to not use resolves and instead just have all the API logic inside the controller, however this causes the scope of each of the 3 resources to be limited to their controller and that is it. Meaning, if you are in the Movies controller, you have no visibility into the Authors resources because Authors are scoped to only the "Authors" controller. This makes things like web sockets less efficient and even unusable.
Am I doing something wrong here which is causing me to not get the desired functionality or is this not possible with this kind of architecture?

Get current view. Reload view later

I implemented a back button that allows the user to go back to the previous view. However, I only want this back button to affect a particular "String of Links".
Example: Say I have a side bar with three links and a main view like so,
______________________
view8 | |
view1 | MAIN VIEW |
view9 | |
______|_______________|
The view1 link pops view1 into the main view. view1 then contains a link to view2 then view2 then contains a link to view3 and so on. We will call this our "String of Links".
The view9 link pops view9 into the main view. Currently, on view9, there is a back button that will take you back to the previous page. That back button uses window.history.back(); to route to the last view.
The problem I am having is that if the user first clicks view8 then clicks view9, the back button on view9 will send the user back to view8. But I want the user to go back to the last view on the "String of Links".
How would I go about saving a view on the "String of Links" and then later calling that view and loading it into the main view?
You need to use angular's routeProvider or my personal favorite ui-router, which would allow you to enable browser history in the way that you describe.
The nasty way would be to manipulate the url using $location and ... ugh ... , I'm sorry I just gagged

Angular JS filters using Firebase data

I have some data in firebase that looks like this:
|
|
--users
|
--1
|
--email:"hello#gmail.com"
--name:"User 01"
--2
|
--email:"hello2#gmail.com"
--name:"User 02"
--chat
|
---JU9ZpBj7P9dWgNYN4To
|
--email:"hello#gmail.com"
--content:"Hi, i'm user 01! How are you?"
--user:"1"
--timestamp:"123456789"
---JX8ZpBnli7hliwehlfi
|
--email:"hello2#gmail.com"
--content:"Hi, i'm user 02! I'm great thanks!"
--user:"2"
--timestamp:"123456789"
I get the chat data from firebase in an object called 'messages', and my HTML/angular looks like this:
<ul class="chat" ng-repeat="message in messages | orderByPriority | reverse">
<li>
<strong>{{message.user | uid2name}}</strong> {{message.content}}
</li>
</ul>
So what I want to do is grab message.user and convert it from a userid into a name. I figured a good way would be to use a filter:
.filter('uid2name', function(loginService, $rootScope) {
// Takes a userid and outputs a users name
return function(input) {
var ref = new Firebase('https://<myapp>.firebaseio.com/users/' + input);
return $firebase(ref).name;
};
})
Now this works fine, but it does so by essentially polling firebase multiple times per second - not what I want to do at all. I have thought about caching the response in $rootScope but this seems a bit sloppy. What's the best way going about this? I am open to any ideas, I am not wed to the idea of using a filter.
Filters are one the things I love a bout Angular, but they are too heavy (since they are evaluated with every digest cycle) and definitely does't suite to your approach, unless you use cache (just don't store it in $rootScope, create a cache service instead).
Firebase is all about performance, in most cases normalization is your enemy. You already store user email, why don't you also store user name as well?
Changing the data structure to include userId in the URL of your Chat data structure may help: Data Modeling Best Practices in Firebase/AngularFire
In the end, I solved this problem by using the angular-cache plugin (the default angular cache-factory is good but it lacks a few useful features). I cached the users in order to use a filter without hammering firebase.

Resources