Loading a list of controllers dynamically - javascript

I can't get my head wrapped around solving the following problem using angularJS.
I have a list view containing different kinds of data elements. Each element in itself is a view and has its own controller.
Now I want to iterate over this Array of the data items and based on recordType attribute, I want to initialize a controller with a template and finally add it to the list view.
At the moment I am using ng-include="item.recordType+'.html'" to dynamically load the template and the template itself has an ng-controller tag which loads the relevant controller. But I am not sure if this is the best approach.
<div class="data-item" ng-repeat="item in container.record_collection">
<div ng-include src="item.tRecordType + '.html'"></div>
</div>
Say record-type is apples
<script id="apples.html" type="text/ng-template">
<div ng-controller="ApplesController as apple">
<!-- ... HTML TEMPLATE ... -->
</div>
</script>

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

Dynamically load templates (partials) in Angular.js

I'm trying to load a template into an Angular app depending on a parameter. It would be inside a ng-foreach:
<body ng-app="MyApp" ng-controller="ExampleController as example">
<div ng-repeat="item in example.items" class="someClass" ng-switch="item.type">
<!-- load a different template (partial) depending on the value of item.type -->
</div>
</body>
Fiddle: https://jsfiddle.net/rsvmar2n/1/
Can I somehow do that? I was thinking about using ng-switch: https://jsfiddle.net/rsvmar2n/6/
But I'm sure there's a more angular way to do it.
Edit: I would like NOT to do an http request for every partial I would load (and I think ngInclude does that.
Edit2: Ended using ng-include and cached templates. https://jsfiddle.net/rsvmar2n/24/
You can call a function which returns the id of the template in ng-include and use cached templates. The working example shows what you can do.
the function in your controller which handles the template looks like:
$scope.getTemplate = function(item) {
switch(item.type)
{
case "type1":
return 'testtype1.html';
default:
return 'testtype2.html';
}
}
and your html
<script type="text/ng-template" id="testtype1.html">
<p>This is the template 1</p>
</script>
<script type="text/ng-template" id="testtype2.html">
<p>This is the template 2</p>
</script>
<body ng-app="MyApp" ng-controller="ExampleController">
<div ng-repeat="item in items" class="someClass">
<!-- load a different template (partial) depending on the value of item.type -->
<div ng-include="getTemplate(item)"></div>
</div>
</body>
Create directive for that, something like:
app.directive('myDirective', function(){
return {
restrict: 'E',
scope: {item: '=item'},
templateUrl: function(element, attrs){
if (!attrs.type) return 'default.html';
return attrs.type + '.html';
}
}
});
Then you can create different templates like type1.html, type2.html...
And in controller you just do:
<my-directive ng-repeat="item in items" item="item", type="item.type">
Using ng-include lets you dynamically assign the source - so in your parent template you could have
<div ng-include src="templateName"></div>
where templateName is a variable name in your controller
$scope.templateName = 'path/to/my/template.html';
and changing this value within a digest should dynamically update the contents for you
Based on conditions you can load single or multiple templates as shown below.
With ng-switch
ng-if="item.type=='type2'||item.type=='type3'"
LoadMultipleTemplate To load multiple template based on your selections.
LoadSingleTemplate load single template.
Edit
With ng-include, this way you can load dynamic views.
in this example I've not put any condition. but within ng-repeat you can put another ng-repeat and based on inner ng-repeat you can do the stuff. But for inner ng-repeat you will have to make according json object.
loadViews
<div ng-repeat="item in example.items" class="someClass" >
<ng-include src="item.type + '.html'">{{item.type}}</ng-include>
</div>

Laravel 5.1 - Javascript not loaded

My app gets the views from an ajax request by navigation.
So when i click a link in my menu i retrieve all the Html that my view contains.
My javascript is included inside the main template and of course all my calls works.
But once i need for example to create an animated filter gallery inside a specific view, the javascript for that view doesn't work.
This is how i've organized my app:
My template
<!-- !Doctype -->
#include('partials.doctype')
<!-- Menu -->
#include('partials.menu')
<!-- Cont -->
<section id="content-wrapper">
#include('ajax.index')
</section>
<!-- Footer -->
#include('partials.footer')
<!-- Javascript -->
#include('partials.javascript')
</body>
</html>
My Controller (if there's an ajax call i retrieve the view without #extends() and #section(), otherwise i retrieve my full view):
// load page
public function loadPage($page){
return (\Request::ajax()) ? view('ajax.'.$page)->render() : view('pages.'.$page);
}
My views:
For my purpose i've created 2 type of views, one extended and one with only the html i need from my ajax calls.
a) extended, it's inside "pages" folder:
#extends('main')
#section('cont')
#include('ajax.shop')
#stop
b) only html, for ajax calls, inside "ajax" folder:
<div class="content">
<div class="container-fluid">
<div class="row page-title-box">
<h3 class="page-number">N. 67</h3>
<h1 class="page-title">Shop</h1>
</div>
</div>
</div>
I don't understand where to put my javascript for this view if i need to implement an animated filter gallery. I've tried to put javascript inside the view but my app crashed.
Your javascript should be in your public folder in a folder like public/js.
Then in your partials.javascript include your js:
<script src="/js/main.js"></script>

AngularJS controller executes twice (not because of router)

From what I read, the most common cause of this problem is when the controller is included in the template and in the route provider. In my case, only the parent template containing this html is being included in the router, and has its own controller. The sub-templates are being included as a result of a menu selection
So, whenever the menu item is selected, the template gets loaded in, and everything in the controller executes twice. Can it be a product of the the ng-switch or ng-include?
<span ng-switch on="selection">
<div ng-switch-when="0">
<div ng-include="'partials/one.html'" ng-controller="oneController"></div>
</div>
<div ng-switch-when="1">
<div ng-include="'partials/two.html'" ng-controller="twoController"></div>
</div>
<div ng-switch-when="2">
<div ng-include="'partials/three.html'" ng-controller="threeController"></div>
</div>
</span>
Edit:
The included partials do not include the controller again. I've triple checked that these controllers are not mentioned anywhere other than this piece of code. The contents of the one/two/three partials look like this, and the controller still runs twice.
<div>Nothing to see here.</div>
I am making an educated guess here... but does your "'partials/one.html'" also have a ng-controller="oneController" in it? If so, you either need to remove the ng-controller declaration from your include div or from your partial.

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