Angular directive not working in ionic.js - javascript

I have some troubles to get my directive to load in my ionic.js web app using angular.
I can pass the variable {{someTitle}} from the controller to the template, however the directive does not get loaded, i.e. <div class="blaha" ng-transclude>abc123</div> does not get passed to the template... Am I missing something fatal below:
Ionic template:
<ion-view title="Roll the Dice">
<ion-content has-tabs="true">
<div my-dice>{{someTitle}}</div>
<div class="card">
<div class="item item-text-wrap">
{{someTitle}}
</div>
</div>
<button class="button button-dark button-full button-positive">
Full Width Block Button
</button>
</ion-content>
</ion-view>
Controller code:
'use strict';
angular.module('TrueDice.controllers', [])
// A simple controller that fetches a list of data from a service
.controller('HistoryIndexCtrl', function($scope, TrueRandomService) {
if($scope.rands="undefined"){
$scope.rands = [];
}
TrueRandomService.getRand(1).success(function(data){
$scope.rands.unshift(data);
console.log(data);
});
})
.controller('HistoryDetailCtrl', function($scope, $stateParams, TrueRandomService) {
//currently empty
}).controller('RollViewCtrl', function($scope){
$scope.someTitle="BLA";
}).directive('my-dice', ['$rootScope', function($rootScope) {
return {
restrict: 'E',
template: '<div class="blaha" ng-transclude>abc123</div>',
replace: true,
transclude: true,
scope: {},
controller: function($scope, $element) {
//currently empty
}
}
}]);

Remove - from directive name:
directive('myDice', ['$rootScope', function($rootScope) {
and according to restrict: 'E', you should place element in html:
<my-dice>{{someTitle}}</my-dice>
example

Related

Angular directives, only one works per page

I have little problem with my angularJS directive, i want to display 2 photos in different way by using other html codes, but here comes a problem, that only one directive can works per page, the second one works only when i comment the previous one, there are no any errors in the browser console so i totally losing my mind trying to figure how to fix this problem.
ps displayed photos are taken form json file.
Angular:
(function(angular) {
'use strict';
angular.module('SinglePost', ['ngSanitize', 'ui.bootstrap'])
.controller('Controller', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
var weburl = document.URL;
var postId = weburl.substr(-2, 2)
$http.get(link + 'json=get_post&post_id=' + postId).then(function(response, date, content) {
$scope.content = response.data.post;
$scope.CategoryID = response.data.post.categories[0].id;
IDcategory = $scope.CategoryID
console.log(IDcategory)
$sce.trustAsHtml(content);
});
}])
.directive('myPost', function() {
return {
restrict: 'AEC',
scope: {
myPost: '='
},
templateUrl: '../common/directive/single-post.html'
};
});
})(window.angular);
(function(angular) {
'use strict';
angular.module('SinglePostsCategory', ['ngSanitize', 'ui.bootstrap'])
.controller('Controller', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
$http.get(link + 'json=get_category_posts&id=1').then(function(response, date, contents) {
$scope.myList = {
items: [
$scope.content = response.data.posts[0],
$scope.content = response.data.posts[0]
]
}
});
}])
.directive('myPost', function() {
return {
restrict: 'A',
scope: {
myPost: '='
},
templateUrl: '../common/directive/single-subpost_category.html'
};
});
})(window.angular);
HTML:
<div class="col-md-12">
<div ng-app="SinglePost">
<div ng-controller="Controller">
<div my-post="content">
<h1>CONTENT</h1></div>
</div>
</div>
<div class="row">
<div ng-app="SinglePostsCategory">
<div ng-controller="Controller">
<div ng-repeat="content in myList.items">
<div my-post="content">
<h1>CONTENT</h1></div>
</div>
</div>
</div>
</div>
</div>
any suggestion how to fix it? :)
function(angular) {
'use strict';
angular.module('SinglePost', ['ngSanitize', 'ui.bootstrap'])
.controller('SingleController', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
var weburl = document.URL;
var postId = weburl.substr(-2, 2)
$http.get(link + 'json=get_post&post_id=' + postId).then(function(response, date, content) {
$scope.content = response.data.post;
$scope.CategoryID = response.data.post.categories[0].id;
IDcategory = $scope.CategoryID
console.log(IDcategory)
$sce.trustAsHtml(content);
});
}])
.directive('mySinglePost', function() {
return {
restrict: 'AEC',
scope: {
myPost: '='
},
templateUrl: '../common/directive/single-post.html'
};
});})(window.angular);
angular.module('SinglePostsCategory', ['ngSanitize','ui.bootstrap'])
.controller('SinglePostsController', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
$http.get(link + 'json=get_category_posts&id=1').then(function(response, date, contents) {
$scope.myList = {
items: [
$scope.content = response.data.posts[0],
$scope.content = response.data.posts[0]
]
}
});
}])
.directive('mySinglePostsCategory', function() {
return {
restrict: 'AEC',
scope: {
myPost: '='
},
templateUrl:'../common/directive/singlesubpost_category.html'
};
});})(window.angular);
Rename your directive or your Controller name, Sometimes within the same page with two modules with the same controller name could cause the problem. I recommend to change both Controller names to be distinguishable.
For what I have seen I dont know why you need two module within one page . Can you combine it into one module and use two controllers?
HTML:
<div class="col-md-12">
<div ng-app="SinglePost">
<div ng-controller="SinglePostController">
<div my-single-post="content">
<h1>CONTENT</h1></div>
</div>
</div>
<div class="row">
<div ng-app="SinglePostsCategory">
<div ng-controller="SinglePostsController">
<div ng-repeat="content in myList.items">
<div my-single-posts-category="content">
<h1>CONTENT</h1></div>
</div>
</div>
</div>
</div>
You can not create same name directives even in the different module.
the module is used to divide the develop module,but it can't avoid polluting the namespace.if you want to use the module B in module A,you just need to inject module B like
angular.module('SinglePost', ['ngSanitize', 'ui.bootstrap','SinglePostsCategory'])
but make sure the directive and controller's name is different

AngularJS display json by directive

I have little problem with AngularJS, I wanted to make directive to display json imported from other website, directive working, but it doesnt show anything from angular binds(when i was using this code by just putting it hardway, everything was working).
HTML
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<my-post info="post"></my-post>
</div>
</div>
ANGULAR
(function(angular) {
'use strict';
angular.module('docsIsolateScopeDirective', ['ngSanitize', 'ui.bootstrap'])
.controller('Controller', ['$scope','$http','$sce', function($scope, $http, $sce) {
$http.get(link+'json=get_recent_posts&callback=&count=1').then(function(response, date, contents){
$scope.contents = response.data.posts;
$sce.trustAsHtml(contents);
});
}])
.directive('myPost', function() {
return {
restrict: 'E',
scope: {
customerInfo: '=info'
},
templateUrl: 'single-post.html'
};
});
})(window.angular);
SINGLE-POST.HTML
<article>
<div class="news-container">
<span class="news-category">{{content.categories[0].title}}</span>
<h1 class="news-title">{{content.title}}</h1>
<span class="news-date">{{content.date}}</span>
<div class="news-image">
<img src="{{content.thumbnail_images.full.url}}" />
</div>
<!-- .news-image -->
<div class="news-entry">
<p ng-bind-html="content.content">{{content.content}}</p>
</div>
</div>
Any ideas? :)
You save your response as
$scope.contents = response.data.posts;
And you pass into directive variable post . Maybe you should pass contents ?
And also in your directive you have customerInfo not content.
its always better to use jsonp for calls to outer domains.
Can you try doing this?
$http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})
Whitelisting urls is also apt.
Pass $scope.contents to info.
$scope.contents = response.data.posts;
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<my-post info="contents"></my-post>
</div>
</div>
You need to use customerInfo in the template single-post.html and also pass contents scope object to your directive
Additionally, Using trustAsHtml() method correctly.
$scope.contents = $sce.trustAsHtml(response.data.posts);
Here is a simplified example:
(function(angular) {
'use strict';
angular.module('docsIsolateScopeDirective', [])
.controller('Controller', ['$scope',
function($scope) {
$scope.contents = {
title: "test"
};
}
])
.directive('myPost', function() {
return {
restrict: 'E',
scope: {
customerInfo: '=info'
},
template: '<article>\
<h1 class="news-title">{{customerInfo.title}}</h1>\
</article>'
};
});
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<my-post info="contents"></my-post>
</div>
</div>

Angular: Two way binding between Directive and Controller does not work

I am trying to build a Slider as an Angular directive. The Problem is, that I need the value of the Slider in my Controller, so I can send it via Json to a Service. The value is used in the Directive to update the length of a corresponding span and should get updated whenever the Slider is moved the value should be updated in the Directive and in the Controller. Right now it just updates the variable to the value I set in the Controller once and then it just stays as it is.
Controller:
angular.module('MyApp')
.controller('SliderController', ['$scope', '$http', function($scope, $http) {
$scope.m = 5;
$scope.m2 = 45;
}]);
Directive:
angular.module('MyApp')
.directive('slider', function ($rootScope) {
return {
replace: true,
restrict: 'E',
scope:{
value: '='
},
link: function (scope, element, attrs) {
scope.header = attrs.header;
scope.unit = attrs.unit;
scope.min = attrs.min;
scope.max = attrs.max;
scope.step = attrs.step;
// scope.value = attrs.value;
// scope.model = attrs.ngModel;
var calculation = function () {
// console.log(scope.value);
return scope.value / scope.max * 100;
};
scope.onChange = function () {
if( isNaN(scope.value) || parseInt(scope.value) > parseInt(scope.max)) {
scope.value = scope.max;
}
scope.width = calculation();
};
},
templateUrl: '../html/slider.html'
};
});
HTML Template
<div class="slider">
<h3>{{header}}</h3>
<div class="progress">
<div class="span-back">
<span style="width:{{width}}%"></span>
</div>
<input class="input-range" type="range" min="{{min}}" max="{{max}}" step="{{step}}" data-ng-model="model" data-ng-change="onChange()" >
</div>
<div class="input-group">
<input type="text" class="input-value" ng-model="model" data-ng-change="onChange()">
<div class="input-base">{{unit}}</div>
</div>
Index HTML
<div ng-controller="SliderController">
<slider id="floating-div" header="My Slider" min="1" max="250" step="1" unit="testunit" data-ng-model="m2" value="m2"></slider>
</div>
If it's the directive's controller, you should declare it as such. And use the bindToController too.
angular.module('MyApp')
.directive('slider', function ($rootScope) {
return {
controller: SliderController,
controllerAs: 'vm',
bindToController: {
value: '='
},
replace: true,
restrict: 'E',
scope: true,
....
See if that works.
Also, don't forget to import the slidercontroller.
import SliderController from './slider.controller.js';
(or whatever your path/name is)
Or if import is not available, write the controller directly into the same file as the directive. So the same as above, without the import, but add in the controller:
function SliderController($scope) {
... etc
}
Then the controller: SliderController; line in the directive should work.

AngularJS: Requiring a parent directive from child directive

Please consider this Plunk.
I'm trying to set up a test case for complex directive access, but I get an error calling a method from the parent directive:
Parent directive
app.directive('topParentDirective', [
'$compile',
function($compile){
return {
restrict: 'E',
transclude: true,
template: '<h3>I\'m the parent directive.</h3><div ng-transclude></div>',
controller: function($scope) {
$scope.ActivateMe = function(callerName) {
alert('Parent activated from caller ' + callerName);
};
}
};
}
]);
Child directive
app.directive('interactingChildDirective', [
'$compile',
function($compile){
return {
scope: {
name: '#'
},
restrict: 'E',
require: ['^topParentDirective'],
templateUrl: 'interactingChildDirective.html',
link: function($scope, $elem, $attrs, $ctrl) {
var self = {};
console.log($ctrl);
$scope.CallTopParent = function() {
$ctrl.ActivateMe($attrs.name);
};
}
};
}
]);
InteractingChildDirective.html
Contains:
My name is {{name}}, <button ng-click="CallTopParent()">Click me</button>!
Html
<body ng-app="ngApp">
<div ng-controller="myController">
<top-parent-directive>
<interacting-child-directive name="Child 1"></interacting-child-directive>
</top-parent-directive>
</div>
</body>
Issue
TypeError: $ctrl.ActivateMe is not a function
at n.$scope.CallTopParent
Which is the case because $ctrl doesn't seem to be correct.
How can I fix this? It's likely something ridiculously easy ...
It should be
controller: function($scope) {
this.ActivateMe = function(callerName) {
alert('Parent activated from caller ' + callerName);
};
}
Because $ctrl gets required controller's this.
Because you have nested the child in the parents controller you can access it's scope by using
$scope.$parent
in your case:
$scope.$parent.ActivateMe($attrs.name);
Plunker: http://plnkr.co/edit/YyppT9pWnn1PFWJXBAOF?p=info
The answer by estus, combined by the comments, works. To be complete, a working sample of the scenario I was aiming for:
Plunkr sample.
Updated Html
<body ng-app="ngApp">
<div ng-controller="myController">
<top-parent-directive>
<interacting-child-directive name="Child 1">
<meaningless-level-directive header="Sub 1">
<interacting-child-directive name="Child 3"/>
</meaningless-level-directive>
</interacting-child-directive>
<interacting-child-directive name="Child 2">
<meaningless-level-directive header="Sub 2">
<interacting-child-directive name="Child 4"/>
</meaningless-level-directive>
</interacting-child-directive>
</top-parent-directive>
</div>
</body>
meaninglessLevelDirective
As the name suggests this is just to add an extra level:
app.directive('meaninglessLevelDirective', [
'$compile',
function($compile){
return {
scope: {
header: '#'
},
restrict: 'E',
transclude: true,
templateUrl: 'meaninglessLevelDirective.html',
controller: function($scope){
}
};
}
]);
meaninglessLevelDirective.html
<div class="meaninglessLevelStyle">
{{header}}
<div style="padding: 10px" ng-transclude>
</div>
</div>

Directive render from template

I am new to angularjs. I am trying to make an custom element directive loaded from a model. If I use this directive in the HTML file works, but what I want to do is use this directive in a model. It is possible to trigger the directive after define the model ?
JS:
window.app = angular.module('myapp', ['ngSanitize']);
app.directive("myWidget", function() {
return {
restrict: 'E',
template: "<p>Hello World</p>",
};
});
app.controller('page', ['$scope', '$sce', function($scope, $sce) {
$scope.myhtml = $sce.trustAsHtml("<my-widget></my-widget>")
}]);
HTML:
<div ng-app="myapp">
<div ng-controller="page">
<my-widget></my-widget>
<div ng-bind-html="myhtml"></div>
</div>
</div>

Categories