How to make something happen after a template has rendered in emberjs - javascript

So the concept is simple: You come to the app, you have a default template, with a default navigation element. You click a link in that navigation element it renders a new template: #/rails.
From here the default navigation needs to be hidden, and your new nav needs to be rendered.
The way i attempted to approach this, seems a bit silly: what I did was,
SG.Router.map(function(){
this.resource('rails');
});
$(document).ready(function() {
if($('#rails-nav').length !== 0){
$('#main-nav').hide();
}
});
Now the issue with this is that if you go from the default application template, to the rails template via the link - you get two navs unless you refresh that page. My friend stated that I should use something like:
{{outlet nav}} and then render a navigation based on template. The issue is I don't know how to set this up and I have been looking all over the ember site.
Could some one help me out?

If i understood correctly, when you say default template you mean the application template, where all other templates are rendered within its {{outlet}} helper.
There are several approaches to achieve what you want, but a simple one i think would be to use the index template as your default template. In this case evertyhting will be much simpler and work as you require, since you can specify whether the navigation element is shown by placing it inside a template or not.
http://emberjs.jsbin.com/sume/1/edit
hbs
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
This is the default template using <i>index</i>
<br/>
<br/>
<span style="background-color:grey">this is the nav part {{#link-to 'rails'}}go to rails{{/link-to}}</span>
</script>
<script type="text/x-handlebars" data-template-name="rails">
this is the rails app
</script>
js
App = Ember.Application.create();
App.Router.map(function() {
this.resource("rails");
});
Also to make this answer a bit more relevant to the title of the question, in order to do something when a template has rendered one way would be to use the didInsertElement callback of the View class.
App.RailsView = Ember.View.extend({
didInsertElement:function(){
if($('#rails-nav').length !== 0){
$('#main-nav').hide();
}
}
});
http://emberjs.jsbin.com/dido/1/edit

Related

Angular 1 how to properly include external component inside ng-include?

Situation: I have a view where I'm including a fragment with ng-include. The fragment loads perfectly and works as expected when inside view where controller is defined.
My problem is, that when I want to include external component inside the "ng-include" fragment "myView.html", it doesn't show up. When including it inside the main view where the controller is, it shows up and works as expected.
Main view:
<div ng-controller="MyController">
<div data-ng-include src="'views/myView.html'"></div>
<!-- When loaded here, the component shows up -->
<!-- <div id="componentDiv"></div> -->
</div>
Fragment "myView.html":
<div>
<div id="componentDiv"></div>
</div>
The component is loaded inside the "MyController", where "componentDiv" is the "id" of "div" where the component is placed:
var testObj = new TestObj({"container": "componentDiv"});
Trying to do this to be able to use this fragment with full functionality in several places.
Any ideas or suggestions what to look up or try?
IMHO I think that by saying "...to be able to use this fragment with full functionality in several places" you just answered your question. What you need is to build a custom directive and use it in any place you like.
see directive samples e.g. Angular documentation on directives

What's the easiest way to implement routes to show certain views?

I've created a site that has multiple panels that slide in from the right side of the screen.
I want to be able to put a link on each panel that will share my webpage, and when the user comes to the site, that specific panel will be open.
For example:
www.something.com/#/panel-1
Will show my page with panel-1 opened, while:
www.something.com/#/panel-2 will show my page with panel-2 opened.
What's the easiest way to do this? Can I use Ember,Angular, or Backbone's router and views with only simple html? Should I just use something like router.js?
Any help, advice, or links would be appreciated.
Of course you can do that. That's the one of the strongest qualities of ember.js. After declaring your routes, framework can generate all the corresponding controllers and views automatically (it's called convention over configuration). See an example
Ember.Application.create({});
Ember.Router.map(function(){
this.route('panel1');
this.route('panel2');
});
<script type="text/x-handlebars">
{{link-to 'index' 'index'}}
{{link-to 'first panel' 'panel1'}}
{{link-to 'second panel' 'panel2'}}
<!--your panels will be inserted automatically in the outlet property-->
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="panel1">
panel 1
</script>
<script type="text/x-handlebars" data-template-name="panel2">
panel 2
</script>
Demo: http://jsbin.com/dekixayuxa/1/

Ember.js Render multiple views inside static HTML

I'm new to Ember and I'm stuck trying to render views.
The application in context is not a single page application but so far Ember has been playing nice until I started dealing with views.
I'm trying to render more than one view on a single page (which is like a dashboard and has tons of static HTML and a few containers, one for each view).
Sample HTML:
Let's say I would like to render two lists, one inside the "left-container" div and the other inside the right container.
<div class="static-header></div>
<!-- more static content goes here -->
<div id="left-container"></div>
<!-- more static content goes here -->
<div id="right-container"></div>
...
I've tried creating different views and inserting them using the appendTo method (which is described in the Defining a View section of Ember guides) but it throws the error:
Container was not found when looking up a views template. This is most likely due to manually instantiating an Ember.View. See: http://git.io/EKPpnA
and I couldn't find my way using the link that it points to.
Ember code:
var App = Ember.Application.create({});
App.HomeViewLeft = Ember.View.extend({
templateName: 'home-left',
});
var view = App.HomeViewLeft.create();
view.appendTo('#left-container');
I have also tried using a ContainerView as described in Ember api docs:
App.HomeViewLeft = Ember.View.extend({
templateName: 'home-left',
});
var containerView = Ember.ContainerView.create({
classNames: ['container-view'],
});
containerView.pushObject(App.HomeViewLeft.create());
containerView.appendTo('left-container');
But I get the same error.
How should I render each view inside the #left-container and #right-container respectively?
Thanks in advance.
Template:
<div id="here"></div>
<script type="text/x-handlebars" data-template-name="components/my-foo">
{{text}}
</script>
JS:
App = Ember.Application.create({});
Ember.Application.initializer({
name: 'stand-alone-components',
initialize: function(container, application) {
App.MyFooComponent.create({text: 'Hello World', container: container}).appendTo('#here');
}
});
App.MyFooComponent = Ember.Component.extend({
init: function() {
this._super();
this.set('layout', Ember.TEMPLATES['components/my-foo']);
}
});
http://emberjs.jsbin.com/nekowidera/1/edit?html,js,output
It looks like you are trying to make views behave like partials
Move anything static into a partial and include it in your main template like so:
{{partial "header"}}
The lists you want to render can be turned into a component (if the only thing that changes in them is the data).
So you end up with a single view that contains partials and components:
<div class="static-header>{{partial "header"}}</div>
{{partial "static-content"}}
<div id="left-container">{{list-component data=firstList}}</div>
{{partial "static-content"}}
<div id="right-container">{{list-component data=secondList}}</div>
...

AngularJS dynamically set param of ngInclude based on route

I'm trying to dynamically include a template into my index.html. The general structure of index.html is:
<body>
<header ng-controller="Main">
<section>
<!-- global stuff -->
</section>
<section ng-include="moduleName + '/views/menubar.html'">
<!-- module-based stuff -->
</section>
</header>
<div id="view" ng-view></div>
</body>
Sample URL
example.com/<app_name>/index.html#/<module_name>[/method_name]
I can't figure out how to update $scope.moduleName when the route changes. My trouble is two-fold:
The header's controller is Main, not the controller associated with the view, so I can't? update $scope.moduleName from the view's controller (because Main and the view's controller are siblings).
In Main, I tried setting a $scope.$on('$routeChangeSuccess',…), but apparently it is not notified of route changes.
I've thought of setting up a $rootScope.$on listener (as described in SO#15355346) for the route change and broadcasting down to children, who then emit back up their route, which is broadcasted back down so it is available to Main. But that seems heinous.
And I would really prefer to keep the header outside of ng-view.
EDIT I noticed that $route.current.scope has an object named with module_name (possibly because the name of the controller associated with the route's module_name is the same). I'm wondering if I might be able to somehow use the name of that object…
It's hard to say what's wrong in your code without the full picture. Things you show look fine to me.
Please see this plunk I've created to display the ability to do it. Take note that you also can extend route objects with custom properties, like moduleName here:
$routeProvider.when('/page1', {
template: 'one',
controller: 'one',
moduleName: 'firstModule'
});

Ember.js outlets and routes

I've been trying to learn Ember.js for the last two weeks and I've really struggled. I'm hoping for an 'a-ha' moment but each new feature I try to implement always results in hours of failed testing. I just don't seem to be grasping the framework. I feel like I'm working against it. I'm hoping someone can explain a path forward through this simple example.
I am creating a web app that allows the user to pick products that they will sell to a client. There is a list of products they can chose from and then a list of products they've selected.
I imagine a left-column with navigation controls and a main column showing either the selected products or new products they can add to the order. Here is the basic template:
<script type="text/x-handlebars" data-template-name="pc">
<div id="nav">{{outlet nav}}</div>
<div id="main">{{outlet main}}</div>
</script>
Here is the left navigation template:
<script type="text/x-handlebars" data-template-name="nav">
<div class="button">{{#linkTo "pc.add"}}Add Products{{/linkTo}}</div>
</script>
Here is the selected products template:
<script type="text/x-handlebars" data-template-name="selectedProducts">
{{#each p in controller}}
<div class="product">
<h4>{{p.name}}</h4>
</div>
{{/each}}
</script>
Here is the available products template:
<script type="text/x-handlebars" data-template-name="addProducts">
<div id="addProducts" class="addProducts">
{{#each p in controller}}
<div class="product">
<h4>{{p.name}}</h4>
</div>
{{/each}}
<button {{action "addSelectedProducts"}}>Add Selected Products</button>
<button {{action "back"}}>Back</button>
</div>
</script>
I can load the 'pc' template with some already selected products. Great. I can also navigate to the 'Add Products' template. Great. But when I click 'Add Selected Products', I can't figure out how to move the selected products into the controller/model behind the 'Selected Products' template and then get that template to re-render in place of the 'Add Products template'. It's really two question. How do I update the model of another controller from within a different controller? And, how do I then transition from an event to another route?
Can someone show me how you would design the Route(s) and Controllers? I know that's asking a lot. I"m mostly interested in seeing how you respond to an event in the AppProductsController, update SelectedProductsController's model, and then transition to SelectedProductsRoute and have it re-render the template.
I want to believe this is an amazing framework but I just keep hitting walls.
Andrew
How do I update the model of another controller from within a different controller?
Connect controllers using the needs property. So something like:
//in AddProductsController
needs: ['selectedProducts']
addSelectedProducts: function() {
// Now selectedProductsController can be accessed via the controllers property
otherController = this.get('controllers.selectedProducts');
// add the selected ones...
}
See http://emberjs.com/guides/controllers/dependencies-between-controllers/
how do I then transition from an event to another route?
//in AddProductsController
this.transitionToRoute('blogPosts');
See http://emberjs.com/api/classes/Ember.Controller.html#method_transitionToRoute

Categories

Resources