I am trying to use an AngularJS $scope as an HTML attribute rather than viewable text.
main.js
var myApp = angular.module('myApp');
myApp.controller("buttonCtrl", ['$scope', function($scope){
$scope.johnny = [
{quote: 'Anything for My Princess', controller: 'Princess'}
];
}]);
page1.html
<button ng-repeat="button in johnny"
ng-class="dynamic"
class="topcoat-button"
ng-controller="{{button.controller}}" <---- this is what does not work
ng-click="play()">
{{button.quote}}
</button>
How can I fix this so I can add these variables as an attribute value.
Thanks
Angular.js is a bit weird when doing this, but this should work. Also you're using ng-repeat wrong, but it's fixed below.
<button ng-repeat="johnny in buttons"
ng-class="dynamic"
class="topcoat-button"
ng-controller="this.johnny.controller"
ng-click="play()">
{{johnny.quote}}
</button>
Related
Basically I want to achieve like this scenario:
https://i.stack.imgur.com/LLTcK.png
My research led me to $compile, $trustAsHtml,at last directive.
In $compile and $trustAsHtml I can only append static template or only html but can't use dynamic things such ui-sref, ng-click etc.
So, I tried to create directive it is not working and also I am unable to add multiple template on click.
controller :
app.controller('Ctrl', ['$rootScope', '$scope',function ($rootScope, $scope)
{
$rootScope.enableDirective=false;
if(userHasOneApp){// checking some at least one app then only do action
$rootScope.appicon="img_url"; // data which i am passing
$rootScope.appname="App_name"; // data which i am passing
$rootScope.enableDirective=true;
}
}]);
custom directive:
app.directive('headerTemplate', function () {
return {
template:'<a ui-sref="/event" ng-click="editIt()">'
+'<img src="{{appicon}}"></a>'
+'<span>{{appname}}</span>',
scope:{
appname:'=',
appicon:'='
}
};
});
Header view :
<div> class="headerdiv">
<ul ng-if="enableDirective">
<li header-template appicon="appicon">
</li>
</ul>
</div>
Main view :
<div> class="maindiv">
<ui-view></ui-view> <!--basically I want to append template here -->
<button>Add next template</button>
</div>
Where I am doing wrong ?
Well i was facing the same issue
Check out the following link
This will surely help you.
I have implemented this and it worked in my scenario where i wanted to serve a directive when required i.e Lazy Loading of directive
https://www.codeproject.com/Articles/838402/Lazy-loading-directives-in-AngularJS-the-easy-way
Pretty new to angular and having a little trouble getting data from controller and displaying in view using ionic.
I have a function in a controller ('DashCtrl') where I pass through a string to use within the function by using ng-click. For now I just want to take this string and display it in the next view as I have an href on the same element I have the ng-click event.
When I log the string on the next page, it is working and shows up. How do I get to use this in the view?
Heres the code:
HTML
*first page
<ul contentful-entries>
<div ng-repeat="story in $contentfulEntries.items">
<li class="story col col-100">
<a href="#/tab/story/{{story.fields.slug}}" ng-click='storyDetails("{{story.fields.title}}")'>
<p>{{ story.fields.title }}</p>
</a>
</li>
</div>
</ul>
*redirects to this on the ng-click
<ion-view view-title="Story">
<ion-nav-buttons side="left">
<button class="button back-button buttons button-clear header-item" ng-click="goBack()">
<i class="icon ion-ios-arrow-back"> Back</i>
</button>
</ion-nav-buttons>
<ion-content>
<ion-list ng-controller="DashCtrl">
<h1>{{ story.slug }} </h1>
<p> <!-- HERE IS WHERE I WANT TO DISPLAY THE STRING --> </p>
</ion-list>
</ion-content>
</ion-view>
*heres my controller
.controller('DashCtrl', function($scope, $stateParams, $ionicHistory) {
$scope.storyDetails = function($scope, details) {
// here is the data i need to display in the view
// the console.log shows up in the browser
console.log(details);
}
$scope.goBack = function(){
$ionicHistory.goBack();
}
// this is working fine
$scope.story = $stateParams;
})
Save the details string as a controller variable, and then you can access this within the view.
Assign variable details to some other variable like$scope.newVar = details and then in ur view you can display that by just binding it in this way {{newVar}}.
Hope you got it.
I ended up using the $rootScope. I know this may not be the best solution but I am just trying to grasp Angular at the moment.
In my controller I used
.controller('DashCtrl', function($scope, $stateParams, $rootScope, $ionicHistory) {
$scope.goBack = function(){
$ionicHistory.goBack();
}
$scope.storyDetails = function(details) {
$rootScope.details = details;
return $rootScope.details;
}
})
Then I am able to use the $rootScope.details in another controller to use in a function I need the string for.
I know I'm not doing this the Angular way, so if anyone would be kind enough to show me how to do this 'properly' without using the rootScope, I'd be forever in your debt.
I have a little widget I'd like to use over and over on a single page. It has its own controller. Problem is it needs a piece of data to operate (basically a key), and each key is contained in the parent controller.
Here is an example (which is obviously wrong)
http://plnkr.co/edit/VajgOr1LqpLDnbEJcvor?p=preview
script:
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope',
function($scope) {
$scope.keyForChartABC = "somekey1";
$scope.keyForChartXYZ = "somekey2";
$scope.keyForChartLALA = "somekey3";
}
])
.controller('ChartCtrl', ['$scope',
function($scope) {
//todo: have $scope.key assigned from parent somehow
//not shown: use $scope.key to pull data and format chart data
}
])
index:
<!-- ng-init like this is quite wrong -->
<div ng-init="key = keyForChartABC"
ng-include="'chartwidget.html'"></div>
<hr>
<div ng-init="key = keyForChartXYZ"
ng-include="'chartwidget.html'"></div>
<hr>
<div ng-init="key = keyForChartLALA"
ng-include="'chartwidget.html'"></div>
chartwidget:
<div ng-controller="ChartCtrl">
<p>Drawing chart for data: {{key}}</p>
<p>some chart directive here</p>
</div>
As you can see in the plunker, what I tried here with ng-init doesn't work - key for all the sub-controllers end up with the same value.
I've gotten this to work with ng-repeat and an array of data in the parent, somehow $index gets set in each child to the right index and stays that one value. But I'd like to avoid using ng-repeat in this case so I can have more control of the layout.
Creating re-usable widgets is exactly the purpose of Directives. You can create a directive which handles the output of your widget quite easily.
I forked your plunker and modified it to change it to use a directive.
Here are a few highlights:
First, your template no longer needs the controller defined within it.
<div>
<p>Drawing chart for data: {{key}}</p>
<p>some chart directive here</p>
</div>
Next, the directive is defined, with an isolate scope which is unique to each instance of the directive:
.directive('chartWidget', function(){
return {
restrict: 'E',
scope: {
key: '='
},
templateUrl : 'chartwidget.html'
}
})
Lastly, the directive is declared in the HTML. Note the camel-case name of the directive in the JavaScript, but the hyphenated name in the HTML:
<div>
<chart-widget key="keyForChartABC"></chart-widget>
<hr>
<chart-widget key="keyForChartXYZ"></chart-widget>
<hr>
<chart-widget key="keyForChartLALA"></chart-widget>
</div>
Edit
I updated the plunker to show binding the directive property to an inner controller. This method uses the ControllerAs syntax to define the controller, and binds the directive's scope to the controller scope.
Relevant changes:
.directive('chartWidget', function(){
return {
restrict: 'E',
scope: {
key: '='
},
templateUrl : 'chartwidget.html',
controller: 'chartWidgetController',
controllerAs: 'ctrl',
bindToController: true
}
})
.controller('chartWidgetController', function(){
console.log(this.key);
})
And a small change to the template to support ControllerAs:
<div>
<p>Drawing chart for data: {{ctrl.key}}</p>
<p>some chart directive here</p>
</div>
Note that trying to use ng-controller= in the template will cause the template to have a different scope object from the scope object created for the directive, and the controller would not have access to the properties defined on the directive.
Also note, bindToController is a feature of angular 1.3.x or higher. in angular 1.2.x or earlier, your only option was to use $scope.$watch to monitor the isolate scope for changes.
I am an angular beginner & trying to introduce angular in a legacy application. The page structure looks like this
<html ng-app="demoApp">
<div class="static-parent">
<div class="dyanamic" ng-controller="SimpleController">
<ul>
<li ng-repeat="cust in customers">
{{cust.name}} - {{cust.city}}
</li>
</ul>
</div>
</div>
</html>
The "dyanamic" div is added to dom when a certain button is clicked.
As this controller div is being added dynamically, i tried to load angular afterwards by calling angular bootstrap
angular.bootstrap(document,['demoApp']);
After running the above statement,
3 Li elements are getting created in the dom
But no data is being seen
on the web page. The Li elements are empty
>> angular.element(".dynamic").scope().customers; returns 3 customer objects as expected.
>> angular.element(".dynamic").scope().$apply(); did not help either.
Can you please suggest where I am going wrong? Tried other answers on stackoverflow but didn't seem to help.
Controller code:
//setting up controller
var demoApp = angular.module("demoApp", []);
var controllers = {};
controllers.SimpleController = function($scope){
$scope.customers = [{name:'dave', city:'auckland'},{name:'abe', city:'City2'}, {name:'ram', city:'City3'}];
};
demoApp.controller(controllers);
Code for adding the div dynamically:
var template = Handlebars.compile( $("#template-content-content-container").html() );
$("static-parent").html(template(data));
angular.bootstrap('.page .row', ['demoApp']);
Angular version: 1.0.6
On 1.2.28, calling angular.bootstrap(document,['demoApp']) or angular.bootstrap('.dynamic',['demoApp']);`
is giving
Error: error:btstrpd
App Already Bootstrapped with this Element
Following is the browser screenshot -
Please, check the third (accepted) answer to this: Angular bootstrapping after load of html
(direct link: Loading an AngularJS controller dynamically)
I think, you have to "compile" anything, which is added after a first 'bootstrap' call
Also, I've made this fiddle yesterday to describe my trouble, I think it fits yours.
http://jsfiddle.net/21neg0ox/
var app = angular.module('app', []);
angular.element(document).ready(function () {
angular.bootstrap(document, ['app']);
});
//c1
app.controller('c1', ['$scope', '$compile', c1Fn]);
app.controller('c2', ['$scope', '$compile', c1Fn]);
function c1Fn($scope){
$scope.isAlive = 'is alive';
}
setTimeout(wtf, 500);
function wtf(){
var myLovelyHTML = '<div ng-controller="c2">c2 {{isAlive}}</div>';
document.getElementById('c2-wrap').innerHTML = myLovelyHTML;
}
Im trying to make my first modal using Angular, but it seems that the $modal cant even be found! Here is my code:
myController = ($scope, $modal) ->
$scope.OpenModal = ->$modal.open(
templateUrl: 'Modal.html'
)
And the HTML points to the OpenModal function as follows -
<div ng-controller="myController">
<button ng-click="OpenModal()">Modal</button>
</div>
But when I click the button, I get the error Cannot read property 'open' of undefined. Why is that? Shouldn't the modal object be injected in?
I found the issue. I had already included ui.bootstrap in my app, but I forgot to put $modal in the controller dependencies.