ng-repeat not working with onsen ui - javascript

I'm going nuts, this is such a small thing but I can't find a solution...
I have this js file (the angularjs app is initialized in the begining of the html document)
app.controller('slidingMenuCtrl', function($scope) {
$scope.categories = [
{title: 'Festas', icon: 'ion-ios-pint', notifications: 3},
{title: 'Palestras', icon: 'fa-microphone', notifications: 0}
];
$scope.test = 'aaa';
});
and somewhere in my html
<ons-template id="menu.html" ng-controller="slidingMenuCtrl">
<ons-page>
<div ng-repeat="x in categories">
{{x.title}}
</div>
<div>
{{test}}
</div>
</ons-page>
</ons-template>
The div with ng-repeat shows nothing, but the one without it shows 'aaa' correctly, why?

ons-template template doesn't support ng-controller directive, basically it needs an idea to process a template and thereafter a processing if we ask for template over http it returns registered ons-template with that id, here you had menu.html
You could do same thing as that by having script tag with type text/ons-template there. Its just same as type/ng-template in angular.
Template
<script type="text/ons-template" id="main.html">
...content here...
</script>
Add ng-controller over ons-page will make it working by instantiating controller specified ng-controller directive.
Code
<ons-page ng-controller="slidingMenuCtrl">
<div ng-repeat="x in categories">
{{x.title}}
</div>
<div>
{{test}}
</div>
</ons-page>

Related

Loading local template into external template

Sorry about the title, not certain of a better subject line.
In my ionic project I have a popover window that I use alot but its repeated a lot through different pages. Currently, every popover is uniquely defined in every controller/page view....which means I need to edit every instance of the popover in every page if I want to change one element of the page.
To clean things up, I want to move the embedded script/template to an external file that would be called like:
$ionicPopover.fromTemplateUrl('templates/popover.html', {
scope: $scope,
animation: 'slide-in-up',
focusFirstInput: false
}).then(function(popover) {
$scope.popover = popover;
});
Easy enough...however, some popovers require custom HTML & custom $scope variables. Is it possible to define local <script> template code that can be passed into the external template? Something like:
Main template:
<ion-view id="view">
<ion-nav-title>
...
</ion-nav-title>
<ion-content id="thisContent">
<script id="popoverExtras.html" type="text/ng-template">
<div id="customDiv1"> {{data1}} .. some content .. </div>
<div id="customDiv2"> {{data2}} .. more content .. </div>
</script>
</ion-content>
</ion-view">
External Template:
<ion-popover-view>
<ion-header-bar>
<h1 class="title" style="text-align:center;">{{popTitle}} </h1>
</ion-header-bar>
<ion-content drag-content=“false”>
<div id="subject">{{popSubject}}</div>
<div id="message">{{popMessage}}</div>
<script id="popoverExtras.html" type="text/ng-template">
</script>
</ion-content>
</ion-popover-view>
And still load the entire external + local template into a single popover view with the standard load:
$ionicPopover.fromTemplateUrl('templates/popover.html', {
scope: $scope,
animation: 'slide-in-up',
focusFirstInput: false
}).then(function(popover) {
$scope.popover = popover;
});

Passing value out of uib-accordion scope to the parent scope

I am using the uib-accordion directive from ui-boostrap for AngularJS.
I have a question about passing value out of the transcluded directive, uib-accordion-group.
When simply setting a variable to ng-model inside the accordion, it will be attached to the accordion scope, rather than the parent main scope, though it looks like it is in the main scope due to the transclude directive.
In order to pass the value inside the accordion out to the main scope, I need to do something like ng-model="$parent.$parent.$parent.data2 which seems wrong.
Is there a way to do it gracefully?
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function($scope) {
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.3.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="AccordionDemoCtrl">
<script type="text/ng-template" id="group-template.html">
<div class="panel {{panelClass || 'panel-default'}}">
<div class="panel-heading">
<h4 class="panel-title" style="color:#fa39c3">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span
ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" style="text-align: right" ng-transclude></div>
</div>
</div>
</script>
<uib-accordion close-others="oneAtATime">
<uib-accordion-group heading="Static Header, initially expanded" is-open="true">
<div>
Simple data model
<input type="text" ng-model="data" />Anti-pattern data2 model
<input type="text" ng-model="$parent.$parent.$parent.data2" />
</div>
<div>
I read "{{data}}" inside the accordion
</div>
<div>
I read "{{data2}}" inside the accordion
</div>
</uib-accordion-group>
</uib-accordion>
<div>
How do I read "{{data}}" OUTSIDE the accordion
</div>
<div>
Data2 seems fine "{{data2}}" OUTSIDE the accordion
</div>
</div>
</body>
</html>
I had a related issue quite recently, and I ended up modifying the ui-bootstrap-tpls-0.14.3.js file. On line 239 you can see I've added a property called 'model' to the accordion directive's scope object.
scope: {
heading: '#', // Interpolate the heading attribute onto this scope
isOpen: '=?',
isDisabled: '=?',
model: '=' // Custom property added
},
Then in the controller, I've added an object called item1 to the controller's scope and given it a property called name:
$scope.item1 = {
name: 'test1'
};
Lastly, add a 'model' attribute to the accordion group directive and specify item1 as the value to pass into the accordion directive:
<uib-accordion-group model="item1" heading="Static Header, initially expanded" is-open="true">
You should now be able to set the object's property values in the accordion as well as access them outside of the directive.
Here's a plunk with your code modified to work.
http://plnkr.co/edit/44x8pH?p=preview
I'm not super happy with modifying the UI bootstrap file, but I couldn't come up with a better way to do it. Obviously you'll need to have your own copy of the file stored locally so you can modify it, and I'd suggest adding .custom to the filename to remind you that it's been modified. Probably pop in some comments too so you can migrate any changes you make to a future version of it in case you want to upgrade.
I know it may be very late, and a little bit of purpose, but I ran into a similar issue: I had a value to pass to the template. Inspired by Chris answer, I found a hack that does’nt change uib files:
I passed the value I want to ng-disable, which I used as a temporary variable.
<div uib-accordion-group ... is-disabled="color">
Then in my accordion template, I put isDisabled back to it’s default false value.
<div class="panel-heading" ng-init="color = isDisabled; isDisabled = false">
After this you can use the color angular variable anywhere in the template.
Here is the corresponding plunker : https://embed.plnkr.co/ExktoE4RCXFrn6SoYZIR/
note: It may also work to pass an object in which you have a value containing isDisabled wanted value ({foo: 'bar',.., isDisabled: true}). And then you pass this value back to isDisabled

Angular.js ng-repeat doesn't display content

I am trying to load some content using ng-repeat with Angular.js. I set up a controller which will create an array, and corresponding HTML uses ng-repeat to display all elements in the array.
HTML:
<div class="list-group" ng-controller="MainController as ctrl">
<p class="list-group-item cat" ng-repeat="element in ctrl.current_articles">{{ element }}</p>
</div>
JS:
angular.module('newsclassifier', [])
.controller('MainController', ['$http', function($http){
var self = this;
self.current_articles = [1,2,3,4,5];
}]);
Now on running this code, I am able to see that rows for 5 elements are being created in the corresponding div. However, no content is displayed.
I tried using even the $scope syntax, but to no difference. I am running version 1.4.8 of Angular.js.
Is there something amiss here?
There is a typo in your markup.
ng-controller="ctrl as MainController"
should be
ng-controller="MainController as ctrl"

How to insert HTML by id using something like AngularJS ng-include

I'm using AngularJS and compiling a directive into my main page. The directive has a set of buttons that change depending on what is happening in the directive.
I would like to move the buttons to something like a menu-bar in my page, but the menu-bar is not part of the directive.
Would it be possible to use something like ng-include to insert the buttons in the menu-bar?
An example of what I would like to do:
<body ng-app="myApp" ng-controller="Controller">
<nav class="navbar">
<ul class="nav nav-pills">
<li>
<button>A permanent button</button>
</li>
<div ng-include="#other-buttons></div>
</ul>
</nav>
<my-directive></my-directive>
<script type="text/javascript">
angular.module('myApp', [])
.controller('Controller', ['$scope', function($scope) {
$scope.data = someData;
}])
.directive('myDirective', function() {
return {
template: '<div id="other-buttons" ng-switch="data">
<div ng-switch-when="this">
<li><button>This button</a></li>
</div>
<div data-ng-switch-when="that">
<li><button>That button</a></li>
</div>
</div>'
};
});
</script
</body
So depending on some data the directive template will be different, which should change the content in the nav-bar. How would doing that work?
You can use $templateCache to set and get templates, and then reference them by the ids you gave them. You can see the examples on the page.
myApp.run(function($templateCache) {
$templateCache.put('buttons.html',
'<div id="other-buttons" ng-switch="data">
<div ng-switch-when="this">
<li><button>This button</a></li>
</div>
<div data-ng-switch-when="that">
<li><button>That button</a></li>
</div>
</div>'
);
});
and then load to the ng-include with
<div ng-include=" 'buttons.html' "></div>
Considering that your directive and controller share the same scope, and that your navbar falls within your controller, they should act the same.
However, if you were to use this setup in different parts of the application that do not share the same scope, I would suggest you set up a service that will bridge the gap between the two.

AngularJS ng-repeat display content in separate view

I'm working on a basic news feed app. What I need is for a specific news article, entry.content, to display in a separate view after a click. Both controllers have access to the data, but I need a synchronized click event so the second controller knows which specific article to display. I've been working on this for awhile & couldn't find relevant links on google or here where a secondary view was involved. I need a separate view b/c I have to add a lot more HTML to that page & eventually click(previous/next) between articles. I have an example which is working where the click event happens, but the content displays in the current view then hides after click.
I have a Plunker: http://plnkr.co/edit/lk66pRb7A6DkGM7NQKF7?p=preview
Here is the index.html code:
<body ng-app="FeedApp">
<h1>News Feed</h1>
<div ng-controller="NewsCtrl">
<div id="main">
<div ng-view=""><!-- angular yield --></div>
</div> <!-- main -->
</div> <!-- NewsCtrl -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="main.js"></script>
</body> <!-- FeedApp -->
Here is the home.html code:
<div ng-repeat="new in news">
<h3 ng-repeat="entry in new.entries" ng-if="$index < 3">
{{entry.title}}
</br>
Display this story</br>
Desired: click this Link, go to #/article & display this story
<p class="news-entries" ng-show="show" ng-bind-html="TrustSnippet(entry.content)"></p>
</h3>
</div> <!-- new in news -->
Currently, in the article.html file I only have a back button as I'm not sure what to put in there. All other code is in the Plunker, but I can add here if it will help.
I was thinking this might be be solved using current $index value, but I just don't know at this point.
Any help is appreciated.
You probably just want to use $routeParams like so:
here's a Plunker
route
.when("/article/:articleId", { . .
Link
<a href="#/article/{{$index}}" . . .
Param
FeedApp.controller("ArticlesCtrl", ["$scope", "$routeParams", '$http',
function($scope, $routeParams, $http) {
var index = $routeParams.articleId;
Article Object
$scope.article = $scope.news[0].entries[index];
I would omit the entries bit altogether and I would probably use a factory to manage/maintain the data.

Categories