I have a parent component that is using transclude functionality. In its transcluded part as a default there is the child component:
export class ParentController {
// some logic here
}
angular.module('dmp').component('parentObject', {
bindings: {
},
controller: ParentController,
transclude: true,
templateUrl: 'test/parent.html'
});
}
export class ChildController {
}
angular.module('dmp').component('childObject', {
bindings: {
},
require: {
parentCtrl: '^parentObject'
},
controller: ChildController,
templateUrl: 'test/child.html'
});
}
index.html:
<parent-object>
</parent-object>
parent.html
<div ng-transclude>
<child-object></child-object>
</div>
Note that <child-object> is in the transclude part of parent object
I get the following error:
Controller 'parentObject', required by directive 'childObject', can't be found!
if I make it like this it works as expected but this is not my case.
<parent-object>
<child-object></child-object>
</parent-object>
Thanks
EDIT related to gyc comment.
If I understood correctly I can remove the <div ng-transclude> part and just use the child object without transclusion. This is ok but I want later on to say:
<parent-object>
<some-other-object></some-other-object>
</parent-Object>
And then the <child-object> will be replaced by the <some-other-object>. If I do not use transclusion this will not happen and the <child-object> will remain.
try change this in the childObject definition
require: {
parentController: '^parentObject'
}
maybe parentCtrl is not a defined alias for parentController
camelcased components are dash delimited as dom-elements, so it shoud look like this:
angular.module('dmp').component('childObject', {
bindings: {
},
require: {
parentCtrl: '^parent-object'
},
controller: ChildController,
templateUrl: 'test/child.html'
});
Related
Call a function on parent controller that is declared in is child directive.
Parent controller HTML
<div ng-click="testFunction()"></div>
Parent controller js
$scope.testFunction = function(){
$scope.functionFromChildDirective()
}
Child directive js
function TestDirective() {
return {
restrict: 'EA',
scope: {
},
templateUrl: '',
controller: function($scope) {
"ngInject";
$scope.functionFromChildDirective = function(){
console.log("TEST")
}
}
}
}
export default {
name: 'testDirective',
fn: TestDirective
};
Just delete the empty scope deceleration, by defining it you are creating a new isolate scope. If you don't declare the scope in the directive definition object it will just inherit the parents scope. However with this approach the child directive can only be used once (i.e can't be repeated) as each instance of will just overwrite the $scope.functionFromChildDirective property.
Use the ng-ref directive to bind the controller to a parent variable:
<test-directive ng-ref="testAPI">
</test-directive>
function TestDirective() {
return {
restrict: 'EA',
scope: {
},
templateUrl: '',
controller: function() {
this.testFn = function(){
console.log("TEST")
}
}
}
}
To invoke it:
<div ng-click="testAPI.testFn()"></div>
The ngRef directive tells AngularJS to assign the controller of a component (or a directive) to the given property in the current scope.
For more information, see AngularJS ng-ref Directive API Reference.
I am trying to use a single modal dialog function to house multiple templates. I send the call to create the dialog box an input and I am trying to call various ng-include files based upon that input. However, it seems that the ng-include files are never called.
Is there something I am missing?
Dialog Call
function showDialog(ev, thisItem, modalType)
{
$mdDialog.show({
controller: 'DialogController',
controllerAs: 'vm',
templateUrl: 'app/main/apps/views/templates.html',
locals:{
modalType : modalType
thisItem : thisItem
},
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
fullscreen: true
})
.then(function(data) {
vm.selectedRef=data;
// Call to server to update the references
}, function() {
});
};
The template that should be calling the various lower templates
<md-dialog aria-label="" id="marginDialog" class="dialogItem" ng-cloak>
<span ng-if="vm.modalType=='bibEdit'"
ng-include="app/main/apps/views/editReference.tmpl.html">
</span>
<span ng-include="app/main/apps/templates/editMargins.tmpl.html">
</span>
I can confirm that the variables reach the template and are correct and that they are correct in the controller. However, the include files are simply not called.
I've had really mixed results mixing ng-includes with angular material components, so generally I try to avoid it now.
What I would try to do in this case is write a function that determines the correct template url, and then pass that as the dialog config object:
function showDialog(ev, thisItem, modalType)
{
var template;
var getTemplate = function(){
switch(modalType){
case 'one':
template = 'dialog1.html';
break;
case 'two':
template = 'dialog2.html';
break;
}
}();
$mdDialog.show({
controller: 'DialogController',
controllerAs: 'vm',
templateUrl: template,
locals:{
modalType : modalType
thisItem : thisItem
},
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
fullscreen: true
})
.then(function(data) {
vm.selectedRef=data;
// Call to server to update the references
}, function() {
});
};
Here is a working codepen
Use a directive. That works inside an md-dialog.
(function() {
// Add the directive to the module
angular.module("YourApp").directive('editMargins', EditMarginsFactory);
// Factory Method
function EditMarginsFactory()
{
// Construct and return the instance
return {
restrict: 'E',
scope: false,
templateUrl: "app/main/apps/templates/editMargins.tmpl.html"
};
}
})();
Then, instead of using ng-include in your other template, just do this:
<edit-margins></edit-margins>
Note that the use of scope: false in the directive causes it to use the parent scope, the scope used by the template you added the directive to.
I need to provide an optional parameter for a directive, which can be used to surround the directive's template. This is a basic example of what I have:
angular
.module('test')
.directive('dropdownField', dropDownFn);
function dropDownDirective Fn(termParameters, restService) {
return {
scope: {
'markup' : "=?"
},
bindToController: true,
controllerAs: "vm",
templateUrl: "dropdown.tpl.html",
controller: function ($scope, $element, $attrs) { ... }
}
}
HTML could look like this:
<dropdown-field
markup="<div class='thisIsTheSurroundingMarkup'></div>"
></dropdown-field>
or this:
Inside the controller:
$scope.thisIsTheSurroundingMarkupFromTheController = "<div class='thisIsTheSurroundingMarkup'></div>";
<dropdown-field>
{{ thisIsTheSurroundingMarkupFromTheController }}
</dropdown-field>
Both would/should generate the following outcome:
<div class='thisIsTheSurroundingMarkup'>
<select ...>...</select> <-- this comes from dropdown.tpl.html
</div>
I guess this is one with ngTransclude, however, I am not sure how. Could anybody point me into the right direction? Thanks a lot!
Could fix this by myself.
compile: function compile(tElement, tAttrs) {
tElement.wrap(tAttrs.markup);
},
I have a directive <my-directive> that is an element. I do not use link or compile, just:
export default function myDirective() {
return {
restrict: 'E',
scope: true,
templateUrl: 'my-directive.html',
controller: mydirective,
controllerAs: 'mine',
bindToController: {}
}
}
This of course is a fake directive, but the issue I have is being able to add a css class on this directive when it is in the DOM.
if there is anymore information I need to add, please let me know.
You could target the directive's tag from your CSS/scss stylesheet, this way:
Say you have:
<mydirect></mydirect>
So in styles.css:
mydirect {
background-color: red;
}
I have 2 directives within a module. Within one of them, is a templateUrl property. Within that templateUrl, I've made a reference to the other directive, which in turn has a templateUrl.
e.g.
<div> <!--This is my first partial page which uses the SelectorResult directive -->
Here are some results
<div result-carousel>
<!-- here is where some more html should go from result-carousel -->
</div>
</div>
From the module with the directives:
app.directive('SelectorResult', function () {
return {
restrict: 'AE',
scope: {},
templateUrl: '/chooser/Pages/partials/selector-result-tmpl.aspx',
replace: true,
controller: 'SelectorResultController',
controllerAs: 'resultCtrl'
};
});
app.directive('resultCarousel', function () {
return {
templateUrl: '/chooser/Pages/partials/carousel-tmpl.html'
};
});
This is the error I'm getting:
[ngTransclude:orphan] http://errors.angularjs.org/1.2.28/ngTransclude/orphan?p0=%3Cdivlass%3D%carousel-inner%22%20ng-transclude%3D%22%22%3E
I get an error about transclusion, and I've tried some things, but no change. I thought you folks might have ideas.