Access JQuery from Controller or Route - javascript

I have next structure:
builder.hbs (template)
builder.js (route)
builder.js (controller)
I want to execute some jQuery code when template will be rendered. I found old solutions with View and didInsertElement, but I don't have View in this case. So, is it possible to execute jQuery code from route or controller?
jQuery code:
this.$("#filtersMenu").fixedsticky();

You have didInsertElement on the view of the controller. If say you have IndexController then in views/index.js you would have:
export default Ember.View.extend({
didInsertElement: function(){
this.$('#filtersMenu').fixedsticky();
this._super();
}
});
JSFiddle: http://emberjs.jsbin.com/kegere/1/edit?html,js,output besides that globally jQuery is always on Ember.$:
Ember.$('#filtersMenu').fixedsticky();
That said you should consider putting this into a component that's entirely responsible for rendering it.

Related

How to replace a child view with another in AngularJS

I have an SPA written in AngularJS. The main page uses an ng-include attribute to determine which view to load. This is set in JavaScript when someone clicks on a menu which is contained within the main page. However, I've come across a situation where I need to load a different view by clicking a button within another view, essentially replacing it.
I'm trying to figure out how to do this and from what I've researched, I have to use $rootScope and either an $emit or $broadcast call in the child view and a $rootScope.$on method to detect this event.
The thing is, this doesn't seem to work. I have set my breakpoints and stepped through the code, but I always get this error:
Error: [ngModel:datefmt] http://errors.angularjs.org/1.5.7/ngModel/datefmt?p0=2009-07-21T00%3A00%3A00
Here's the code in my parent page controller:
$rootScope.$on('viewChanged', function () {
var menuItem = {
template: 'customerOrders.html' // will be eventually dynamic
};
navigate(menuItem);
});
function navigate(menuItem) {
$scope.activeMenuItem = menuItem;
}
<div data-ng-include="activeMenuItem.template"></div>
In the child page controller:
function changeSelectedView(viewTemplate) {
$rootScope.$emit('selectedViewChanged', viewTemplate);
}
Obviously I'm doing something wrong here. How do I accomplish what I want, or is there a completely different way to do this?
you can use ng-route to work between views. check https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
First of all, the event name in the $emit function and in the $on function did not match, so I made that fix.
function navigateToNewTemplate(event, viewTemplate) {
var menuItem = {
template: buildTemplateUrl(viewTemplate)
};
navigate(menuItem);
}
$rootScope.$on('selectedViewChanged', navigateToNewTemplate);
function changeSelectedView(viewTemplate) {
$rootScope.$emit('selectedViewChanged', viewTemplate);
}

Ember js how can i run a function after model change?

I am using materialize css library and it says
Collapsible elements only need initialization if they are added dynamically
And i add some elements dynamically. So after the view is rendered i should run this function:
$('.collapsible').collapsible({
accordion : false
});
In setupController function i make some requests and after every request finished i setup the controller. When controller gets the model and after the view is rendered with the new model data i should run a function to initialize the ui elments
You have to setup an ember.js component for your accordion and use the didInsertElement hook:
export default Ember.Component.extend({
classNames: ['.collapsible'],
didInsertElement() {
Ember.run.scheduleOnce('afterRender', this, function() {
this.$().collapsible({
accordion: false
});
});
},
});

execute action (javascript function) after ember template is rendered

I have very small web page with emberjs, where I want to show some item list and openlayers map for them, and another map for selected item.
Something like that:
<script type="text/x-handlebars" id="list">
<div class="list">
<div id="list_map"></div>
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" id="list/item" >
<div class="item">
<div id="item_map"></div>
</div>
</script>
<script>
function showListMap() {
listMap = new ol.Map({target:'list_map'});
}
function showItemMap() {
itemMap = new ol.Map({target:'item_map'});
}
</script>
There is no problem to display map for list:
model: function(params) {
var content = [];
var url = 'http://localhost:8080/app/list';
$.ajax({
url: url,
success: function(surveys) {
content.pushObjects(surveys);
showListMap();
}
});
return content;
}
and I have action in item controller that is executed, when opening selected item, but if I try to create item map there (in controllers action) it fails (afaik because there is no such div at that moment in DOM).
So if I could execute action or my function after div is already add to DOM, it should work.
And question would be, how to execute something after template is added to DOM, or that's completely wrong way to do such stuff (than what would be correct ember way)?
I can't say much with seeing full code. But to execute some code after the DOM is rendered you schedule a function on the the run loops afterRender queue.
Ember.run.scheduleOnce('afterRender', this, function() {
//The div should be available now.
});
But if you really need to touch the DOM I recommend you wrap your map code in a component. A component gets a didInsertElement where you can write your maps initialization code.
var component = Em.Component.extend({
setup: function() {
//Do you map init here.
}.on('didInsertElement')
});
There unfortunately isn't a really good route or controller hook that fires off after a page has already rendered. I believe the reason for this is that the developers of Ember think it is an anti-pattern to directly talk to the DOM.
That being said, I think it sometimes is quite handy for complex UI on otherwise static web pages. If you want to do some sort of jquery or use the DOM API after a route has rendered, you can do the following in your route file (as #Dainius correctly points out)
routeName.js
import Route from '#ember/routing/route';
import jQuery from 'jquery';
export default class myRouteFile extends Route {
manipulateDom = function() {
$("#myDiv").css( "color", "red" );
}
init() {
this._super(...arguments)
Ember.run.scheduleOnce('afterRender', this, this.manipulateDom)
}
}

Jquery plugin in emberjs template

Hi im trying to make a simple feed reader using ember.js and feedek. But so far when I try to place the code for the feed, it not working.
Jquery code for feedek (inside the index template in a script tag):
$('#divRss').FeedEk({
FeedUrl: 'http://vikinglogue.com/feed/',
MaxCount: 100
});
Html Code for template:
<script data-template-name="index" type="text/x-handlebars">
<article style="background-color:#fff;" id="divRss"></article>
</script>
When I run this code in the browser, nothing in the template shows up and I'm not getting any errors. I think the issue is caused by not linking feedek in the template but when I tried it, nothing happened. Thanks, any help is appricated.
To use a jQuery plugin in an Ember app, it's usually best to wrap it in a component:
App.FeedEkComponent = Ember.Component.extend({
tagName: 'article',
didInsertElement: function() {
this.$().FeedEk({
FeedUrl: 'http://vikinglogue.com/feed/',
MaxCount: 100
});
}
});
Then in one of your Handlebars templates,
<p>Your feed:</p>
{{feed-ek}}
I would add to Sam's excellent answer as follows:
Make the component reusable by passing in the url as a property
Don't override didInsertElement hook, instead specify that the function should run on 'didInsertElement' event (see here)
http://emberjs.jsbin.com/boguwagisi/1/edit?html,js,output

Simple Javascript not working in my spa app

I am using the Hot Towel template by John Papa. I have a html view called nav.html, which contains the header portion of my spa. Within that, i need to display the name of the person that is logged into the system (i have a server side utility class that handles the query).
The following is from the html in the nav.html view for that-
data-bind="text: LoggedInAs"
Here is the viewmodel code (nav.js)-
define(['services/logger'], function (logger) {
var vm = {
activate: activate,
title: 'Nav View'
};
return vm;
//#region Internal Methods
function activate() {
logger.log('Nav View Activated', null, 'Nav', true);
return true;
}
//#endregion
});
My problem is that i am not sure how to do this. i tried adding nav.js to my viewmodels folder, but the javascript does not run. I thought durandal would have picked it up like the other viewmodels. The only difference between the nav.js and the other view models is that the other view models are triggered by clicking on a link (wired through route.mapnav).
What am i missing here? How do i get the javascript to run without a user clicking on a link? When the page loads, I need nav.js to run in order to populate the LoggedInAs data-bind.
Make sure that you are activating your nav view. In the example code you have given in the comment above, it would need to be this:
<header> <!--ko compose: {view: 'nav', activate: true} --><!--/ko--> </header>

Categories

Resources