I have a directive that uses ng-model controller and gets it model value from the controller it's inside, "myController". I'm using transclude=true and ng-transclude. This is a general purpose directive that I want to allow my colleagues to re-use. I want to let the consumer click the button and it set ngModel value to whatever value they want but basically always some object. How do I properly set that up? I realize inside the directive I can call ngModel.$setValue or $setViewValue etc... Sorry I am still new to angularjs, specifically directives. Also should I be using a controller inside the directive? I know the object definition for directives has that ability although I don't really know how or when to leverage that. Lastly is it ok to transclude controllers into directives, as in "nestedInDirController"? Thanks for any tips, tricks, examples, or advice.
jsfiddle here
<div ng-controller="myController">
<div foo-directive="" ng-model="viewModel.foo">
<div ng-controller="nestedInDirController">
<various-controls-in-here />
</div>
</div>
</div>
angular.module('myApp', [])
.directive('fooDirective', function(){
var template = '<div><div ng-transclude></div> <button ng-click="someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
return {
transclude: true,
require: '?ngModel',
template: template,
pile: function(tElement, tAttrs, transclude){
return function(scope, element, attrs, ngModel){
}
}
};
});
function myController($scope){
$scope.viewModel = { foo : { bar: 'baz'}};
}
function nestedInDirController($scope){
$scope.someFunc = function(){
alert('I was called');
//how can I set ng-model in foo-directive from this controller?
}
}
I have a directive that uses ng-model controller and gets it model value from the controller it's inside, "myController". I'm using transclude=true and ng-transclude. This is a general purpose directive that I want to allow my colleagues to re-use. I want to let the consumer click the button and it set ngModel value to whatever value they want but basically always some object. How do I properly set that up? I realize inside the directive I can call ngModel.$setValue or $setViewValue etc... Sorry I am still new to angularjs, specifically directives. Also should I be using a controller inside the directive? I know the object definition for directives has that ability although I don't really know how or when to leverage that. Lastly is it ok to transclude controllers into directives, as in "nestedInDirController"? Thanks for any tips, tricks, examples, or advice.
jsfiddle here
<div ng-controller="myController">
<div foo-directive="" ng-model="viewModel.foo">
<div ng-controller="nestedInDirController">
<various-controls-in-here />
</div>
</div>
</div>
angular.module('myApp', [])
.directive('fooDirective', function(){
var template = '<div><div ng-transclude></div> <button ng-click="someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
return {
transclude: true,
require: '?ngModel',
template: template,
pile: function(tElement, tAttrs, transclude){
return function(scope, element, attrs, ngModel){
}
}
};
});
function myController($scope){
$scope.viewModel = { foo : { bar: 'baz'}};
}
function nestedInDirController($scope){
$scope.someFunc = function(){
alert('I was called');
//how can I set ng-model in foo-directive from this controller?
}
}
Share
edited Jun 19, 2013 at 23:53
Hcabnettek
asked Jun 19, 2013 at 23:44
HcabnettekHcabnettek
12.9k38 gold badges129 silver badges192 bronze badges
1
-
1
nestedInDirController
already has access to the properties defined onmyController
's scope, because the scope prototypically inherits. Inside yournestedInDirController
, this works:console.log($scope.viewModel)
and so does this:$scope.viewModel.foo.bar = "testing";
– Mark Rajcok Commented Jun 20, 2013 at 22:02
2 Answers
Reset to default 2http://jsfiddle/jSEba/
This is one way to satisfy your need by using event emission.
i.e. letting directive to $broadcast
event into its child scope,
so that transcluded child scope can catch via $on
to react to the
button click.
angular.module('myApp', [])
.directive('fooDirective', function(){
var template = '<div><div ng-transclude></div> <button ng-click="someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
return {
transclude: true,
template: template,
link: function(scope, elem, attrs) {
scope.someFunc = function() {
scope.$broadcast('buttonclick', { valname: attrs.fooDirective });
};
}
};
});
function myController($scope){
$scope.viewModel = { foo : { bar: 'baz'}};
}
function nestedInDirController($scope){
$scope.$on('buttonclick', function(event, arg) {
$scope.$eval( arg.valname + " = 'new value'");
});
}
I'm suspecting there may be a better way, though.
This is another solution using a Shared service between the directive and the controllers.
(You could create a better service to enforce the required data structure to be shared between the controllers in that specific case, instead of the general example.)
Here is a jsfiddle http://jsfiddle/PguFh/15/ (a little updated after I wrote the code below).
index.html
<div ng-controller="myController">
<div foo-directive="" ng-model="viewModel.foo">
<div ng-controller="nestedInDirController">
<pre>{{viewModel.foo|json}}</pre>
</div>
</div>
</div>
app.js
angular.module('myApp', [])
.factory('Shared', function() {
var shared = {};
return {
set: function(value) {
shared = value;
},
get: function() {
return shared;
}
}
})
.directive('fooDirective', function(Shared){
var template = '<div><div ng-transclude></div> <button ng-click="shared.someFunc()">I want to update ng-model in the directive, which in turn will update myController $scope.viewModel.foo</button></div>';
return {
transclude: true,
require: '?ngModel',
template: template,
pile: function(tElement, tAttrs, transclude){
return function(scope, element, attrs, ngModel) {
scope.shared = Shared.get();
}
}
};
});
function myController($scope, Shared){
$scope.viewModel = { foo : { bar: 'baz'}};
Shared.set({
viewModel: $scope.viewModel,
someFunc: function() { alert('default?'); }
});
}
function nestedInDirController($scope, Shared){
var shared = Shared.get();
shared.someFunc = function(){
alert('I was called');
//how can I set ng-model in foo-directive from this controller?
shared.viewModel.foo.bar = "baz.modified";
}
}