Reputation: 1287
I have directive 'copyPaste' which copies element value to the element specified in 'destination' attribute.
// html code
<div ng-app='app'>
<div ng-controller="mainController">
<input type='text' ng-model='firstInput' copy-paste destination='secondInput'>
<input type='text' ng-model='secondInput'>
<!-- following does not work -->
<input type='text' ng-model='param.firstInput' copy-paste destination='param.secondInput'>
<input type='text' ng-model='param.secondInput'>
</div>
</div>
//directive code
module.directive('copyPaste',['$rootScope',function($rootScope){
return {
restrict:'A',
link:function(scope,element,attrs,ctrl){
var destination=attrs.destination;
scope.$watch(attrs.ngModel, function (v) {
scope[destination]=v
});
}
}
}])
//controller
module.controller('mainController',['$scope',function($scope){
$scope.firstInput='hello'
}]);
Above code works if I pass simple variable. If I pass object , array it does not work . How can I pass array and objects to directive as string then use as variables. I dont want to run directive in isolate scope, in isolate scope I need to call $scope.$apply to update binding so trying to avoid isolate scope.
Upvotes: 0
Views: 234
Reputation: 2330
Ok so I got this to work. This should do it see -> plunk:
basically im traversing your scope tree to find the object for which you want to set the value. Not the prettiest but it gets the job done
var module = angular.module('app', []);
module.directive('copyPaste', ['$rootScope', function($rootScope) {
return {
restrict: 'A',
link: function(scope, element, attrs, ctrl) {
var destination = attrs.destination;
scope.$watch(attrs.ngModel, function(v) {
var splitted = destination.split('.');
if (splitted.length > 1) {
var value = null;
var lastKey = "";
for (var i = 0; i < splitted.length; i++) {
if(value == null) {
value = scope[splitted[i]];
} else {
if(value[typeof splitted[i] == 'Object']) {
value = value[splitted[i]];
} else {
lastKey = splitted[i];
}
}
}
value[lastKey] = v;
} else {
scope[destination] = v;
}
});
}
}
}])
module.controller('mainController', ['$scope', function($scope) {
$scope.firstInput = 'hello';
$scope.secondInput = "";
$scope.param = {};
$scope.param.secondInput = "";
$scope.param.firstInput = "Again";
}]);
Upvotes: 1
Reputation: 548
I think you should use an event instead of $watch, it would be more performant. Have a look at ngChange (https://docs.angularjs.org/api/ng/directive/ngChange)
I think the problem could be due to $watch that is not checking your variable properly.
You could try to set the objectEquality boolean to true (doc here https://docs.angularjs.org/api/ng/type/$rootScope.Scope )
scope.$watch(attrs.ngModel, function (v) {
scope[destination]=v
}, true); // <-- deep object check
Upvotes: 0
Reputation: 131
You can use JSON.stringify
for convert value to a JSON string, and then later use JSON.parse
which turns a string of JSON text into a Javascript object
Upvotes: 0