Breaking HTML into management templates for AngularJS - backbone.js

So I am trying to evaluate AngularJS as I think it is interesting however it is quite different from what I have been using which is BackboneJS. As part of this evaluation I want to take a few page of my existing Backbone application and try to port them over to AngularJS. So I have the following html layout:
<html>
<head>
</head>
<body>
<div class="page-wrapper">
<div class="header-wrap">
<ul>
<li>Ryan Zec</li>
<li>Admin</li>
<li>Logout</li>
</ul>
</div>
<div class="content-wrap">
<form>
<input type="text" name="username" value="" />
<input type="password" name="password" value="" />
<input type="button" value="Login" />
</form>
</div>
<div class="footer-wrap">
<span>Copyright © 2012 - Ryan Zec
</div>
</div>
</body>
</html>
Now in backbone I would have the div with the -wrap classes be empty and to contents for each section one would go in individual templates (and each section could have more than one template that might display in it). There would then be a view associated for each template to would attach to the correct element and display the contents of the template in it.
Now with AngularJS, it is discouraged to do direct DOM manipulation everywhere except in directives. So I am wondering what is the best way to have the same setup in AngularJS that I do with BackboneJS keeping in mind that the content of these sections need to be switched out for different content based on the page/url they are viewing? (I know I can add the ng-directive-name to the div so on initial load, it load correctly but how do I get it to reload to different data when the page is switched in a single page application).

Answer is directives :)
you can either use this -> http://jsfiddle.net/thaqL/
or just download chrome -> go to http://angularjs.org -> press F12 -> check out how they did it
hope it helps.
cheers

I think for the time being the best answer is ngInclude. I think that the AngularJS team wants to make routes more powerful (based on something I remember reading) in the future (like multiple views per route where each should should have a controller for the header, a controller for the footer, and a controller for the main content) but until then ngInclude should hopefully get me by.

Related

How to make proper container component using Angular?

In the project I work on there are list "manipulation controls", like:
The parts of this controls are the same at 90% of the pages. So I'm thinking about writing "manipulation controls" Component, so I wouldn't change sizes at every page, just in Component's template if I need to (all these col-xs-*), or just copy/paste html for each input separately.
<div class="row">
<div class="col-xs-7 form-inline">
<div class="col-xs-9">
<!-- Search input -->
</div>
<div class="col-xs-3">
<!-- Type select -->
</div>
</div>
<div class="col-xs-5 form-inline right">
<sort-by ng-model="sortBy" ng-change="setCurrentPage(1);" values="{{sortValues}}"></sort-by>
<items-per-page ng-model="itemsPerPage" ng-change="setCurrentPage(1);"></items-per-page>
</div>
</div>
Is it a good idea to make such "container" component? Is there any tutorial on how to make it properly (some of the inputs might be hidden, i.e. list is small and there is no need for pagination, every placeholder, title are unique in general, so there might be many variables to pass)?
This is more or less architecture question, I'm not experienced in this, but to my mind the idea of writing such component is good. If I'm mistaken or the question isn't specific enough, please argument it.
Yes, it is a good idea to turn reusable code into components.
Yes, passing configuration variables is how you would customize it for each use case. Using ng-show, ng-hide, ng-if, ng-switch, ng-class, ng-style, etc ... there are many ways to implement the options in your template.
When you have a large number of options, it is common practice to pass them as one object. (ie. config="{foo: 'bar', baz: 'biz'}" vs foo="bar" baz="biz").
Yes, it's a good idea: that's the purpose of directives (or components, in the new 1.5x implementations): inject in your HTML some reusable components in an intelligent way.
Think if you ever need to bind a variable to your "containers": you'll be able to do it easily and with no pain at all, by using directives/components.
Alternatively, if you don't need any form of logic inside your "containers", you could use ng-include with templates to inject html in your pages, like this:
<div ng-include"myContainer.html"></div>
and somewhere in your "templates.html"..
<script type="text/ng-template" id="myContainer.html">
<!-- content -->
</script>
What you are looking for is Angular directive (https://docs.angularjs.org/guide/directive)

ng-repeat triggers every time i reload my view

I'm creating a website with multiple tabs, and one of them is listing elements, it's the Product tab.
I've got a problem with "ng-repeat", I want to fill a HTML depending on a table of table in angular on the tab, it works fine on the first load, but if I go to another tab and then go again on the product tab, the "ng-repeat" repeats once more and it stacks with the first one.
Example:
Firstload: an apple and a strawberry are loaded fine.
Secondload: I now have apple strawberry and apple strawberry
And so on.
<slick dots="true" prev-arrow="null" next-arrow="null" init-onload="true" data="productsTab">
<div class="productsPage scrollBar" ng-repeat="tab in productsTab">
<div class="productsProduct" ng-repeat="product in tab">
<div class="productsProductTitle">{{product.name}}</div>
</div>
</div>
</slick>
I can also say that I load my data from a factory that I get in controller this way:
productsFactory.build().then(function(facto) {
$scope.productsTab = facto;
});
Hope you can help me!
I think your problem is that init-onload. I am not sure what it does, but if it triggers the call to the controller in some way, it also triggers the promise every time you go back to the tab. You can cache the results from the promise inside the service. Here's an article from this site on how to cache promises:
Caching a promise object in AngularJS service
Hope this will help.
Here is example how to handle multiple ng-repeats, I hope this will help you.
http://plnkr.co/edit/TfGMm1SgpRmgFSTuTuE0?p=preview
<script>
var app=angular.module('myapp',[])
app.controller('demo',function($scope){
$scope.products={
product:[{
name:'abc'
}]
}
})
</script>
</head>
<body ng-app="myapp" ng-controller="demo">
<div ng-repeat="product in products">
<div ng-repeat="p in product">
<span>{{p.name}}</span>
</div>
</div>
</body>
I noticed from the docs I found here https://github.com/vasyabigi/angular-slick that there are no parenthesis on on-init=true. Not sure if that matters.
When I have issues with arrays not resetting I use angular.copy() an empty list variable before loading to the scope. That way I know the array is empty before I add anything to it.

Angular: Using ng-disabled if forms in partials in child controllers have ng-invalid attribute

I've been struggling with this for a few hours, and I'm coming up blank. I wouldn't build this this way, but this is someone else's code and refactoring it all is way beyond the scope of my part of the project. I need something that works within the way it's currently built. Here is a rough approximation of what the html looks like:
<div ng-controller=OuterController as outerController>
<button ng-click="save()" ng-disabled="?????">Save</button>
<div ng-controller="PartialController as partialController>
<div partial which can be replicated a bunch of times and called recursively>
<form name="partialForm></form
</div>
</div>
</div>
So, there can be a ton of instances of partialForm within the dom, which may be different degrees of childhood from the OuterController, and I want to be able to check if any of them have ng-invalid for the ng-disabled on the save button.
Any thoughts? :)

AngularJs - Switch directive mode

I would like to create a header directive with swappable controls. The header contains a search input, which stays the same throughout the application, and a number of buttons, which differ from page to page.
I considered usage of child directives that can be passed as arguments, but they are giving me a multidir error due to multiple template requests:
header.html
<div class="header">
<input type="text">
</div>
mode1.html
<div class="controls">
<buutton>Foobar</button>
</div>
Usage:
<app-header mode1>
My second thought was to use a shared service that initializes the available controls by determining the active mode. That seems a little weird, though.
How can I create such a directive with different modes?

angular ui-router maintaining state between tabs

Would like to know the best way to preserve state between tabs. I use bootstrap tabs and angular ui-router. I've a google map in one of the tabs and don't want to reload the map when user selects that tab. Please advise.
Thanks
I think what you are looking for is discussed in this issue: https://github.com/angular-ui/ui-router/issues/63
They are mostly discussing iframes but I believe the same should hold for Google Maps. Unfortunately in the thread they decided that this isn't something that should be implemented in the core release. I haven't tried out the directive they provide (if I get a chance I'll let you know how it goes) but you may be able to get something working with that.
I have actually come across the exact problem you had. My solution was to use styled buttons as my tabs and ng-show for the map tab:
<div id="info-btns">
<button class="btn" ng-model="view" btn-radio="'info'">
Info
</button>
<button class="btn" ng-model="view" btn-radio="'map'" ng-click="loadMap()">
Map
</button>
</div>
<div class="content" ng-show="view != map">
<div ui-view="info"></div>
</div>
<div id="map-container" ng-show="view == 'map'">
<div id="map" class="content" sitemap>
</div>
</div>
ng-show simply uses display:none to hide the map and hence doesn't cause a refresh. You will need to trigger the map to load the first time it is not hidden otherwise it will render incorrectly, hence loadMap()
If I get a chance I'll set up a jsfiddle of this in practice.

Resources